CI-nightly #1870
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
| name: CI-nightly | |
| on: | |
| schedule: | |
| - cron: '0 22 * * *' | |
| workflow_dispatch: | |
| env: | |
| CYPRESS_VERIFY_TIMEOUT: 180000 # https://docs.cypress.io/guides/guides/command-line#cypress-verify | |
| CVAT_VERSION: "local" | |
| jobs: | |
| check_updates: | |
| runs-on: ubuntu-latest | |
| env: | |
| REPO: ${{ github.repository }} | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| outputs: | |
| last_commit_time: ${{ steps.check_updates.outputs.last_commit_time }} | |
| last_night_time: ${{ steps.check_updates.outputs.last_night_time }} | |
| steps: | |
| - id: check_updates | |
| run: | | |
| default_branch=$(gh api /repos/$REPO | jq -r '.default_branch') | |
| last_commit_date=$(gh api /repos/${REPO}/branches/${default_branch} | jq -r '.commit.commit.author.date') | |
| last_night_date=$(gh api /repos/${REPO}/actions/workflows/schedule.yml/runs | \ | |
| jq -r '.workflow_runs[]? | select((.status == "completed")) | .updated_at' \ | |
| | sort | tail -1) | |
| last_night_time=$(date +%s -d $last_night_date) | |
| last_commit_time=$(date +%s -d $last_commit_date) | |
| echo Last CI-nightly workflow run time: $last_night_date | |
| echo Last commit time in develop branch: $last_commit_date | |
| echo "last_commit_time=${last_commit_time}" >> $GITHUB_OUTPUT | |
| echo "last_night_time=${last_night_time}" >> $GITHUB_OUTPUT | |
| search_cache: | |
| needs: check_updates | |
| uses: ./.github/workflows/search-cache.yml | |
| build: | |
| needs: search_cache | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: CVAT server. Getting cache from the default branch | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/cvat_cache_server | |
| key: ${{ runner.os }}-build-server-${{ needs.search_cache.outputs.sha }} | |
| - name: CVAT UI. Getting cache from the default branch | |
| uses: actions/cache@v4 | |
| with: | |
| path: /tmp/cvat_cache_ui | |
| key: ${{ runner.os }}-build-ui-${{ needs.search_cache.outputs.sha }} | |
| - name: Set up Docker Buildx | |
| uses: docker/setup-buildx-action@v3 | |
| - name: Create artifact directories | |
| run: | | |
| mkdir /tmp/cvat_server | |
| mkdir /tmp/cvat_ui | |
| mkdir /tmp/cvat_sdk | |
| - name: CVAT server. Build and push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| cache-from: type=local,src=/tmp/cvat_cache_server | |
| context: . | |
| file: Dockerfile | |
| tags: cvat/server:${{ env.CVAT_VERSION }} | |
| outputs: type=docker,dest=/tmp/cvat_server/image.tar | |
| - name: CVAT UI. Build and push | |
| uses: docker/build-push-action@v6 | |
| with: | |
| cache-from: type=local,src=/tmp/cvat_cache_ui | |
| context: . | |
| file: Dockerfile.ui | |
| tags: cvat/ui:${{ env.CVAT_VERSION }} | |
| outputs: type=docker,dest=/tmp/cvat_ui/image.tar | |
| - name: Upload CVAT server artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cvat_server | |
| path: /tmp/cvat_server/image.tar | |
| - name: Upload CVAT UI artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cvat_ui | |
| path: /tmp/cvat_ui/image.tar | |
| unit_testing: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: '3.10' | |
| - name: Download CVAT server image | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cvat_server | |
| path: /tmp/cvat_server/ | |
| - name: Download CVAT UI images | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cvat_ui | |
| path: /tmp/cvat_ui/ | |
| - name: Load Docker images | |
| run: | | |
| docker load --input /tmp/cvat_server/image.tar | |
| docker load --input /tmp/cvat_ui/image.tar | |
| docker image ls -a | |
| - name: OPA tests | |
| run: | | |
| python cvat/apps/iam/rules/tests/generate_tests.py | |
| docker compose run --rm -v "$PWD:/mnt/src:ro" -w /mnt/src \ | |
| cvat_opa test cvat/apps/*/rules | |
| - name: Generate SDK | |
| run: | | |
| pip3 install -r cvat-sdk/gen/requirements.txt | |
| ./cvat-sdk/gen/generate.sh | |
| - name: Install test requirements | |
| run: | | |
| pip3 install -e ./cvat-sdk -e ./cvat-cli -r ./tests/python/requirements.txt | |
| - name: REST API and SDK tests | |
| run: | | |
| echo 'Run 1: without cache' | |
| pytest tests/python/ --alluredir=tests/python/allure-results | |
| pytest tests/python/ --stop-services | |
| echo 'Run 2: with cache' | |
| CVAT_ALLOW_STATIC_CACHE="true" pytest tests/python | |
| pytest tests/python/ --stop-services | |
| - name: Upload allure results for REST API tests | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: allure-results-rest-api | |
| path: tests/python/allure-results | |
| - name: Unit tests | |
| env: | |
| HOST_COVERAGE_DATA_DIR: ${{ github.workspace }} | |
| CONTAINER_COVERAGE_DATA_DIR: "/coverage_data" | |
| run: | | |
| docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d cvat_opa cvat_server cvat_db | |
| max_tries=12 | |
| while [[ $(curl -s -o /dev/null -w "%{http_code}" localhost:8181/health?bundles) != "200" && max_tries -gt 0 ]]; do (( max_tries-- )); sleep 5; done | |
| docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.ci.yml \ | |
| run --env PYTHONDEVMODE=1 cvat_ci /bin/bash \ | |
| -c 'python manage.py test cvat/apps -v 2' | |
| docker compose -f docker-compose.yml -f docker-compose.dev.yml -f docker-compose.ci.yml down -v | |
| e2e_testing: | |
| needs: build | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| specs: ['actions_tasks', 'actions_tasks2', 'actions_tasks3', 'actions_tasks4', | |
| 'actions_objects', 'actions_objects2', 'actions_users', | |
| 'actions_projects_models', 'canvas3d_functionality', | |
| 'issues_prs', 'issues_prs2', 'features'] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22.x' | |
| - name: Download CVAT server image | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cvat_server | |
| path: /tmp/cvat_server/ | |
| - name: Download CVAT UI image | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: cvat_ui | |
| path: /tmp/cvat_ui/ | |
| - name: Load Docker images | |
| run: | | |
| docker load --input /tmp/cvat_server/image.tar | |
| docker load --input /tmp/cvat_ui/image.tar | |
| docker image ls -a | |
| - name: Run CVAT instance | |
| run: | | |
| docker compose \ | |
| -f docker-compose.yml \ | |
| -f docker-compose.dev.yml \ | |
| -f tests/docker-compose.file_share.yml \ | |
| -f tests/docker-compose.minio.yml \ | |
| -f components/serverless/docker-compose.serverless.yml up -d | |
| - name: Waiting for server | |
| id: wait-server | |
| env: | |
| API_ABOUT_PAGE: "localhost:8080/api/server/about" | |
| run: | | |
| max_tries=60 | |
| status_code=$(curl -s -o /tmp/server_response -w "%{http_code}" ${API_ABOUT_PAGE}) | |
| while [[ $status_code != "200" && max_tries -gt 0 ]] | |
| do | |
| echo Number of attempts left: $max_tries | |
| echo Status code of response: $status_code | |
| sleep 5 | |
| status_code=$(curl -s -o /tmp/server_response -w "%{http_code}" ${API_ABOUT_PAGE}) | |
| (( max_tries-- )) | |
| done | |
| if [[ $status_code != "200" ]]; then | |
| echo Response from server is incorrect, output: | |
| cat /tmp/server_response | |
| fi | |
| echo "status_code=${status_code}" >> $GITHUB_OUTPUT | |
| - name: Fail on bad response from server | |
| if: steps.wait-server.outputs.status_code != '200' | |
| uses: actions/github-script@v3 | |
| with: | |
| script: | | |
| core.setFailed('Workflow failed: incorrect response from server. See logs artifact to get more info') | |
| - name: Add user for tests | |
| env: | |
| DJANGO_SU_NAME: "admin" | |
| DJANGO_SU_EMAIL: "[email protected]" | |
| DJANGO_SU_PASSWORD: "12qwaszx" | |
| run: | | |
| docker exec -i cvat_server /bin/bash -c "echo \"from django.contrib.auth.models import User; User.objects.create_superuser('${DJANGO_SU_NAME}', '${DJANGO_SU_EMAIL}', '${DJANGO_SU_PASSWORD}')\" | python3 ~/manage.py shell" | |
| - name: Run tests | |
| run: | | |
| cd ./tests | |
| corepack enable yarn | |
| yarn --immutable | |
| shopt -s extglob | |
| if [[ ${{ matrix.specs }} == canvas3d_* ]]; then | |
| npx cypress run \ | |
| --headed \ | |
| --browser chrome \ | |
| --config-file cypress_canvas3d.config.js \ | |
| --spec 'cypress/e2e/setup/setup_canvas3d.js,cypress/e2e/canvas3d_*/**/*.js,cypress/e2e/remove_users_tasks_projects_organizations.js' | |
| else | |
| npx cypress run \ | |
| --browser chrome \ | |
| --spec 'cypress/e2e/setup/setup.js,cypress/e2e/setup/setup_project.js,cypress/e2e/${{ matrix.specs }}/**/*.js,cypress/e2e/remove_users_tasks_projects_organizations.js' | |
| fi | |
| - name: Creating a log file from "cvat" container logs | |
| if: failure() | |
| run: | | |
| docker logs cvat_server > ${{ github.workspace }}/tests/cvat.log | |
| - name: Uploading cypress screenshots as an artifact | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cypress_screenshots_${{ matrix.specs }} | |
| path: ${{ github.workspace }}/tests/cypress/screenshots | |
| - name: Uploading cypress videos as an artifact | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cypress_videos_${{ matrix.specs }} | |
| path: ${{ github.workspace }}/tests/cypress/videos | |
| - name: Uploading "cvat" container logs as an artifact | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: cvat_container_logs_${{ matrix.specs }} | |
| path: ${{ github.workspace }}/tests/cvat.log | |
| - name: Upload Allure results as an artifact | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: allure-results-e2e-${{ matrix.specs }} | |
| path: tests/allure-results-e2e | |
| generate_report: | |
| name: Generate Allure Report and Upload to S3 | |
| needs: [unit_testing, e2e_testing] | |
| if: always() | |
| uses: ./.github/workflows/generate-allure-report.yml | |
| secrets: | |
| AWS_ALLURE_REPORTS_ROLE: ${{ secrets.AWS_ALLURE_REPORTS_ROLE }} |