name: ocelot.social end-to-end test CI on: push jobs: prepare_backend_environment: name: Fullstack | prepare backend environment runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Copy backend env file run: | cp backend/.env.test_e2e backend/.env cp webapp/.env.template webapp/.env - name: Neo4J | Build image uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: neo4j file: neo4j/Dockerfile target: community load: true tags: ghcr.io/ocelot-social-community/ocelot-social/neo4j:community cache-from: type=gha,scope=neo4j cache-to: type=gha,mode=max,scope=neo4j - name: Backend | Build image uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: backend file: backend/Dockerfile target: test load: true tags: ghcr.io/ocelot-social-community/ocelot-social/backend:test cache-from: type=gha,scope=backend-test cache-to: type=gha,mode=max,scope=backend-test - name: Pull third-party images run: | docker pull quay.io/minio/minio:latest docker pull quay.io/minio/mc:latest docker pull maildev/maildev:latest - name: Save all images run: | docker save "ghcr.io/ocelot-social-community/ocelot-social/backend:test" > /tmp/backend.tar docker save "ghcr.io/ocelot-social-community/ocelot-social/neo4j:community" > /tmp/neo4j.tar docker save "quay.io/minio/minio:latest" > /tmp/minio.tar docker save "quay.io/minio/mc:latest" > /tmp/minio-mc.tar docker save "maildev/maildev:latest" > /tmp/mailserver.tar - name: Cache docker images uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4.0.2 with: path: | /tmp/backend.tar /tmp/neo4j.tar /tmp/minio.tar /tmp/minio-mc.tar /tmp/mailserver.tar key: ${{ github.run_id }}-e2e-backend-environment-cache prepare_webapp_image: name: Fullstack | prepare webapp image runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3 - name: Webapp | Build 'test' image uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8 # v6 with: context: . file: webapp/Dockerfile target: test load: true tags: ghcr.io/ocelot-social-community/ocelot-social/webapp:test cache-from: type=gha,scope=webapp-test cache-to: type=gha,mode=max,scope=webapp-test - name: Save image for test jobs run: docker save "ghcr.io/ocelot-social-community/ocelot-social/webapp:test" > /tmp/webapp.tar - name: Cache docker image uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4.0.2 with: path: /tmp/webapp.tar key: ${{ github.run_id }}-e2e-webapp-cache prepare_cypress: name: Fullstack | prepare cypress runs-on: ubuntu-latest steps: - name: Delete huge unnecessary tools folder run: rm -rf /opt/hostedtoolcache - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: 'backend/.nvmrc' cache: 'yarn' - name: Copy env files run: | cp webapp/.env.template webapp/.env cp backend/.env.test_e2e backend/.env - name: Install cypress requirements run: | sudo wget --no-verbose -O /opt/cucumber-json-formatter "https://github.com/cucumber/json-formatter/releases/download/v19.0.0/cucumber-json-formatter-linux-386" sudo chmod +x /opt/cucumber-json-formatter cd backend yarn install yarn build cd .. yarn install - name: Cache docker image uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4.0.2 with: path: | /opt/cucumber-json-formatter /home/runner/.cache/Cypress /home/runner/work/Ocelot-Social/Ocelot-Social key: ${{ github.run_id }}-e2e-cypress list_features: name: List Feature Files runs-on: ubuntu-latest outputs: features: ${{ steps.list.outputs.features }} steps: - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: List feature files id: list run: | FEATURES=$(find cypress/e2e/ -maxdepth 1 -name "*.feature" -printf '%f\n' | sort | jq -R -s -c 'split("\n") | map(select(length > 0))') echo "features=$FEATURES" >> $GITHUB_OUTPUT fullstack_tests: name: E2E | ${{ matrix.feature }} if: success() needs: [prepare_backend_environment, prepare_webapp_image, prepare_cypress, list_features] runs-on: ubuntu-latest strategy: fail-fast: false matrix: feature: ${{ fromJson(needs.list_features.outputs.features) }} steps: - name: Delete huge unnecessary tools folder run: rm -rf /opt/hostedtoolcache - name: Checkout code uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Setup Node.js uses: actions/setup-node@6044e13b5dc448c55e2357c09f80417699197238 # v6.2.0 with: node-version-file: 'backend/.nvmrc' cache: 'yarn' - name: Restore cypress cache uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4.0.2 with: path: | /opt/cucumber-json-formatter /home/runner/.cache/Cypress /home/runner/work/Ocelot-Social/Ocelot-Social key: ${{ github.run_id }}-e2e-cypress restore-keys: ${{ github.run_id }}-e2e-cypress - name: Restore backend environment cache uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4.0.2 with: path: | /tmp/backend.tar /tmp/neo4j.tar /tmp/minio.tar /tmp/minio-mc.tar /tmp/mailserver.tar key: ${{ github.run_id }}-e2e-backend-environment-cache - name: Restore webapp cache uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v4.0.2 with: path: /tmp/webapp.tar key: ${{ github.run_id }}-e2e-webapp-cache - name: Boot up test system | docker compose run: | chmod +x /opt/cucumber-json-formatter sudo ln -fs /opt/cucumber-json-formatter /usr/bin/cucumber-json-formatter docker load < /tmp/neo4j.tar docker load < /tmp/backend.tar docker load < /tmp/minio.tar docker load < /tmp/minio-mc.tar docker load < /tmp/mailserver.tar docker load < /tmp/webapp.tar docker compose -f docker-compose.yml -f docker-compose.test.yml up --detach backend mailserver webapp echo "Waiting for backend (max 120s)..." timeout 120 bash -c 'until curl -sf -X POST -H "Content-Type: application/json" -d "{\"query\":\"{__typename}\"}" http://localhost:4000 > /dev/null 2>&1; do sleep 5; done' echo "Backend is ready." echo "Waiting for webapp (max 120s)..." timeout 120 bash -c 'until curl -sf http://localhost:3000 > /dev/null 2>&1; do sleep 5; done' echo "Webapp is ready." - name: Full stack tests | run tests id: e2e-tests run: yarn run cypress:run --spec "cypress/e2e/${{ matrix.feature }}" - name: Full stack tests | if tests failed, compile html report if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }} run: | cd cypress/ node create-cucumber-html-report.js - name: Full stack tests | if tests failed, upload report id: e2e-report if: ${{ failure() && steps.e2e-tests.conclusion == 'failure' }} uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: name: e2e-report-${{ matrix.feature }} path: /home/runner/work/Ocelot-Social/Ocelot-Social/cypress/reports/cucumber_html_report e2e_status: name: E2E | Status if: always() needs: [fullstack_tests] runs-on: ubuntu-latest steps: - name: Check E2E results run: | if [ "${{ needs.fullstack_tests.result }}" != "success" ]; then echo "E2E tests failed or were cancelled (result: ${{ needs.fullstack_tests.result }})" exit 1 fi