build(deps): bump the symfony group across 1 directory with 32 updates #6776
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| # ** Dynamic analysis ** | |
| # | |
| # Dynamic analysis requires the Share community platform to run during evaluation. Currently Catroweb's dynamic tests | |
| # are mainly UI-tests and a few unit tests. Hence, the tests take multiple hours. To reduce the run time, the tests | |
| # are executed in multiple independent jobs. However, all jobs use the same Catroweb Docker image to reduce build time. | |
| # | |
| # Fork PR support: | |
| # PRs from forks cannot push to GHCR (the GITHUB_TOKEN is read-only for the upstream org's packages). | |
| # For fork PRs the build job exports the image as a tarball artifact instead. Downstream jobs detect which | |
| # delivery method was used and pull/load accordingly. Internal PRs continue to use the fast GHCR path. | |
| # | |
| name: 'Dynamic analysis' | |
| permissions: | |
| contents: read | |
| packages: write | |
| # Run-on every creation, update and merge of a pull request. | |
| # However, prevent checks to be initiated twice if the pull request is a branch on the same repository. (E.g dependabot) | |
| on: | |
| pull_request: | |
| branches: | |
| - '**' # all branches | |
| schedule: | |
| - cron: '0 4 * * *' # Every day at 04:00 UTC | |
| workflow_dispatch: # Allow manual trigger | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.head_ref || github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| REGISTRY: ghcr.io | |
| IMAGE_NAME: catrobat/catroweb-test | |
| jobs: | |
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| # Build: | |
| # | |
| # - In order to save computation time the "app.catroweb" image is only build once during this build phase. | |
| # Other jobs can re-use this image to reduce their build time. With several jobs + the matrix build total | |
| # computation time for this workflow can be highly reduced. This is important since we do not have unlimited | |
| # resources/machines to run the jobs. | |
| # | |
| # - For internal PRs the image is pushed to GHCR. GHCR pulls are fast since GitHub runners have direct | |
| # access to the registry. | |
| # | |
| # - For fork PRs the image is exported as a tarball and uploaded as a GitHub Actions artifact, because | |
| # fork PR tokens lack write access to the upstream org's package registry. | |
| # | |
| build: | |
| name: Build Catroweb Image | |
| runs-on: ubuntu-latest | |
| outputs: | |
| image-tag: ${{ steps.meta.outputs.tags }} | |
| is-fork: ${{ steps.fork-check.outputs.is_fork }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Check if fork PR | |
| id: fork-check | |
| run: | | |
| if [ "${{ github.event_name }}" = "pull_request" ] && [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then | |
| echo "is_fork=true" >> "$GITHUB_OUTPUT" | |
| else | |
| echo "is_fork=false" >> "$GITHUB_OUTPUT" | |
| fi | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Log in to GitHub Container Registry | |
| if: steps.fork-check.outputs.is_fork == 'false' | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Generate image metadata | |
| id: meta | |
| run: | | |
| TAG="${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.event.pull_request.head.sha || github.sha }}" | |
| echo "tags=${TAG}" >> "$GITHUB_OUTPUT" | |
| - name: Build and push Catroweb App Image (internal) | |
| if: steps.fork-check.outputs.is_fork == 'false' | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: docker/Dockerfile | |
| push: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| build-args: APP_ENVIRONMENT=test | |
| cache-from: type=gha | |
| cache-to: type=gha,mode=max | |
| - name: Build Catroweb App Image (fork) | |
| if: steps.fork-check.outputs.is_fork == 'true' | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: . | |
| file: docker/Dockerfile | |
| load: true | |
| tags: ${{ steps.meta.outputs.tags }} | |
| build-args: APP_ENVIRONMENT=test | |
| cache-from: type=gha | |
| - name: Export image as tarball (fork) | |
| if: steps.fork-check.outputs.is_fork == 'true' | |
| run: docker save ${{ steps.meta.outputs.tags }} | gzip > /tmp/catroweb-image.tar.gz | |
| - name: Upload image artifact (fork) | |
| if: steps.fork-check.outputs.is_fork == 'true' | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: catroweb-image | |
| path: /tmp/catroweb-image.tar.gz | |
| retention-days: 1 | |
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| # PhpUnit: | |
| # | |
| # - the tests are executed in our docker since we have many integration tests which access the database, etc. | |
| # One might consider to strictly separate integration and unit tests. Units tests could be executed using | |
| # composer scripts only to reduce the runtime to a few seconds. No build needed + dependencies can be easy cached. | |
| # | |
| # - A code coverage report is pushed to the artifacts where it can be downloaded directly on GitHub. | |
| # Keep in mind the report is not including the tests written for behat. | |
| # | |
| tests_phpunit: | |
| name: PHPUnit | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Log in to GitHub Container Registry | |
| if: needs.build.outputs.is-fork == 'false' | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Pull Docker Image (internal) | |
| if: needs.build.outputs.is-fork == 'false' | |
| run: docker pull ${{ needs.build.outputs.image-tag }} | |
| - name: Download image artifact (fork) | |
| if: needs.build.outputs.is-fork == 'true' | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: catroweb-image | |
| path: /tmp | |
| - name: Load Docker Image (fork) | |
| if: needs.build.outputs.is-fork == 'true' | |
| run: gunzip -c /tmp/catroweb-image.tar.gz | docker load | |
| - name: Tag image for docker-compose | |
| run: docker tag ${{ needs.build.outputs.image-tag }} app.catroweb | |
| - name: Build and Start Docker Containers | |
| run: | | |
| cd docker | |
| docker compose -f docker-compose.test.yaml up -d | |
| - name: Run PHPUnit Tests | |
| run: | | |
| docker exec app.catroweb bin/phpunit --coverage-html tests/TestReports/CoverageReports/PhpUnit \ | |
| --coverage-clover=tests/TestReports/CoverageReports/PhpUnit/coverage.xml | |
| - name: Upload PHPUnit Code Coverage Report | |
| uses: actions/upload-artifact@v7 | |
| if: always() | |
| with: | |
| name: PhpUnitTestReport | |
| path: tests/TestReports/CoverageReports/PhpUnit | |
| - name: Upload Coverage to Codecov | |
| uses: codecov/codecov-action@v6 | |
| with: | |
| files: tests/TestReports/CoverageReports/PhpUnit/coverage.xml | |
| flags: phpunit # optional | |
| name: codecov-umbrella # optional | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| # Behat: | |
| # | |
| # - This job runs all Behat suites parallel using a matrix strategy. This is done since integrations tests which | |
| # are interacting with a browser and the GUI are extremely slow. With a total run-time of over an hour, using this | |
| # approach the run-time can be drastically reduced. The disadvantage, we can't easily create a coverage report | |
| # for the behat scenarios. Something that is considered to be a bad practice anyway since Behat is intended to | |
| # deliver scenario automation in BDD. | |
| # | |
| # - Behat and especially UI tests using Mink tend to flaky. | |
| # A test will only be marked as failed if a test fails more than 3 times in a row. | |
| # Flaky tests should be reduced to a minimum in the codebase! | |
| # | |
| # - Behat only reruns failed tests - Not pending/missing tests or those with exceptions! | |
| # A pending/missing test will NOT result in a failed pipeline! | |
| # This is the reason why the explicit check for the log file had to be added. | |
| # | |
| # - To ease the debugging, besides a log file, screenshots of failing tests are uploaded as artifacts. | |
| # | |
| # Notes: | |
| # - Check the behat.yaml when changing / creating new suites | |
| # - suites will finish their work even if another suite fails (fail-fast: false) | |
| # | |
| tests_behat: | |
| name: Behat | |
| needs: build | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| testSuite: | |
| # --- API suites --- | |
| - api-achievements api-notifications api-media-library api-studio # ~10m combined | |
| - api-authentication api-comments api-followers api-sanitizer api-utility # ~8m combined | |
| - api-moderation | |
| - api-projects-get # split from api-projects (~10m) | |
| - api-projects-write # split from api-projects (~10m) | |
| - api-search api-translation | |
| - api-user | |
| # --- Web suites --- | |
| - web-achievements | |
| - web-admin-1 # split: projects_overview, featured_programs, approve_projects, login, moderation, maintenance (~7m) | |
| - web-admin-2 # split: db_updater, example, feature_flag, mail, media_library, survey, upload, users (~7m) | |
| - web-authentication web-media-library # ~8m combined | |
| - web-code web-project web-scratch-integration web-system web-recommendations # ~8m combined | |
| - web-comments web-reports # ~9m combined | |
| - web-general web-notifications # ~10m combined | |
| - web-profile-1 # split: profile_edit, profile, profile_image, data_export (~9m) | |
| - web-profile-2 # split: follow, user_projects, verification, suspended, many_follower (~9m) | |
| - web-project-details | |
| - web-project-list web-remix-system web-reactions | |
| - web-search web-top-bar | |
| - web-studio | |
| - web-translation | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Log in to GitHub Container Registry | |
| if: needs.build.outputs.is-fork == 'false' | |
| uses: docker/login-action@v4 | |
| with: | |
| registry: ${{ env.REGISTRY }} | |
| username: ${{ github.actor }} | |
| password: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Pull Docker Image (internal) | |
| if: needs.build.outputs.is-fork == 'false' | |
| run: docker pull ${{ needs.build.outputs.image-tag }} | |
| - name: Download image artifact (fork) | |
| if: needs.build.outputs.is-fork == 'true' | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: catroweb-image | |
| path: /tmp | |
| - name: Load Docker Image (fork) | |
| if: needs.build.outputs.is-fork == 'true' | |
| run: gunzip -c /tmp/catroweb-image.tar.gz | docker load | |
| - name: Tag image for docker-compose | |
| run: docker tag ${{ needs.build.outputs.image-tag }} app.catroweb | |
| - name: Build and Start Docker Containers | |
| run: | | |
| cd docker | |
| docker compose -f docker-compose.test.yaml up -d | |
| - name: Warmup the cache | |
| run: | | |
| docker exec app.catroweb bin/console cache:warmup -e test | |
| # Derive a slug for log file names (replace spaces with underscores) | |
| - name: Prepare suite variables | |
| id: suite-vars | |
| run: | | |
| SLUG=$(echo "${{ matrix.testSuite }}" | tr ' ' '_') | |
| echo "slug=$SLUG" >> "$GITHUB_OUTPUT" | |
| # Test Run | |
| # Matrix entries may contain multiple space-separated suites that run sequentially. | |
| - name: Behat ${{ matrix.testSuite }} tests | |
| id: test-run | |
| continue-on-error: true | |
| # - The output will of the tests will be piped to the stdout and into the log file. | |
| # - A return code != 0 stops the execution of further commands in the pipeline. | |
| # "tee" always returns 0, even if the behat test fails. Therefore, we need to exit with the first entry of | |
| # the pipe status, which contains the correct exit code. | |
| run: | | |
| docker exec app.catroweb chmod -R 777 var | |
| OVERALL_EXIT=0 | |
| for suite in ${{ matrix.testSuite }}; do | |
| docker exec app.catroweb bin/behat -s "$suite" -f pretty --xdebug \ | |
| |& tee -a tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log; \ | |
| EXIT_CODE=${PIPESTATUS[0]} | |
| if [ "$EXIT_CODE" -ne 0 ]; then | |
| OVERALL_EXIT=$EXIT_CODE | |
| fi | |
| done | |
| echo "test-run-exit-code=$OVERALL_EXIT" > $GITHUB_ENV | |
| ( exit $OVERALL_EXIT ) | |
| # Missing steps are not rerun by behat, without this step they will be lost in the process | |
| # We must explicitly kill the pipeline if the log contains undefined steps | |
| - name: Check that suite has NO missing steps | |
| if: always() | |
| id: missing-check | |
| run: | | |
| if grep -q 'has missing steps. Define them with these snippets:' tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log; then | |
| cat tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log | |
| exit 1 | |
| fi | |
| # Pending steps are not rerun by behat, without this step they will be lost in the process | |
| # We must explicitly kill the pipeline if the log contains pending steps | |
| - name: Check that suite has NO pending steps | |
| if: always() | |
| id: pending-check | |
| run: | | |
| if grep -q 'pending)' tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log; then | |
| cat tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log | |
| exit 1 | |
| fi | |
| # Chrome exception are problems that can't be fixed with a rerun. However, we can try to run the whole suite one more time | |
| - name: Check for Chrome Exceptions | |
| if: always() | |
| id: chrome-exception-check | |
| run: | | |
| if grep -q '\[DMore\\ChromeDriver\\StreamReadException\]' tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log; then | |
| cat tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log | |
| for suite in ${{ matrix.testSuite }}; do | |
| docker exec app.catroweb bin/behat -s "$suite" -f pretty | |
| done | |
| fi | |
| - name: Upload Behat Test Artifacts | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: logs_${{ steps.suite-vars.outputs.slug }} | |
| path: | | |
| tests/TestReports/Behat/${{ steps.suite-vars.outputs.slug }}.log | |
| tests/TestReports/TestScreenshots | |
| - name: Upload Coverage to Codecov | |
| uses: codecov/codecov-action@v6 | |
| with: | |
| files: tests/TestReports/CoverageReports/Behat/coverage.xml | |
| flags: behat # optional | |
| name: codecov-umbrella # optional | |
| token: ${{ secrets.CODECOV_TOKEN }} | |
| - name: Rerun Behat Tests (1st Attempt) | |
| if: env.test-run-exit-code != '0' | |
| id: test-rerun-1 | |
| continue-on-error: true | |
| run: | | |
| docker exec app.catroweb chmod -R 777 var | |
| OVERALL_EXIT=0 | |
| for suite in ${{ matrix.testSuite }}; do | |
| docker exec app.catroweb bin/behat -s "$suite" --rerun | |
| EXIT_CODE=$? | |
| if [ "$EXIT_CODE" -ne 0 ]; then OVERALL_EXIT=$EXIT_CODE; fi | |
| done | |
| echo "test-run-exit-code=$OVERALL_EXIT" > $GITHUB_ENV | |
| ( exit $OVERALL_EXIT ) | |
| - name: Rerun Behat Tests (2nd Attempt) | |
| if: env.test-run-exit-code != '0' | |
| id: test-rerun-2 | |
| continue-on-error: true | |
| run: | | |
| OVERALL_EXIT=0 | |
| for suite in ${{ matrix.testSuite }}; do | |
| docker exec app.catroweb bin/behat -s "$suite" --rerun | |
| EXIT_CODE=$? | |
| if [ "$EXIT_CODE" -ne 0 ]; then OVERALL_EXIT=$EXIT_CODE; fi | |
| done | |
| echo "test-run-exit-code=$OVERALL_EXIT" > $GITHUB_ENV | |
| ( exit $OVERALL_EXIT ) | |
| - name: Rerun Behat Tests (3rd Attempt) | |
| if: env.test-run-exit-code != '0' | |
| id: test-rerun-3 | |
| run: | | |
| for suite in ${{ matrix.testSuite }}; do | |
| docker exec app.catroweb bin/behat -f pretty -s "$suite" --rerun || exit 1 | |
| done | |
| ## Failure debugging | |
| - name: Debug Failure | |
| if: failure() | |
| run: | | |
| docker ps -a | |
| echo "--- App Logs ---" | |
| docker logs app.catroweb | |
| echo "--- DB Logs ---" | |
| docker logs db.catroweb.test | |
| echo "--- Chrome Logs ---" | |
| docker logs chrome.catroweb |