From deb602578186a8918270cf05d75efd3e72bd9335 Mon Sep 17 00:00:00 2001 From: Yuri Sizov Date: Tue, 1 Aug 2023 20:38:07 +0200 Subject: [PATCH] CI: Extract godot-cpp testing into its own job This ensures that the godot-cpp job has plenty of resources to run its build and avoid being affected by the main build. Additionally: - Extract test tasks into dedicated actions. - Upload artifacts as early as possible. - Ensure that we check master cache before random cache. --- .github/actions/download-artifact/action.yml | 18 +++ .github/actions/godot-api-dump/action.yml | 24 ++++ .github/actions/godot-cache/action.yml | 13 ++ .../actions/godot-converter-test/action.yml | 18 +++ .github/actions/godot-project-test/action.yml | 37 +++++ .github/workflows/godot_cpp_test.yml | 54 ++++++++ .github/workflows/linux_builds.yml | 129 ++++++------------ .github/workflows/macos_builds.yml | 16 +-- .github/workflows/runner.yml | 16 +++ .github/workflows/windows_builds.yml | 16 +-- 10 files changed, 238 insertions(+), 103 deletions(-) create mode 100644 .github/actions/download-artifact/action.yml create mode 100644 .github/actions/godot-api-dump/action.yml create mode 100644 .github/actions/godot-converter-test/action.yml create mode 100644 .github/actions/godot-project-test/action.yml create mode 100644 .github/workflows/godot_cpp_test.yml diff --git a/.github/actions/download-artifact/action.yml b/.github/actions/download-artifact/action.yml new file mode 100644 index 000000000000..58c2aa906071 --- /dev/null +++ b/.github/actions/download-artifact/action.yml @@ -0,0 +1,18 @@ +name: Download Godot artifact +description: Download the Godot artifact. +inputs: + name: + description: The artifact name. + default: "${{ github.job }}" + path: + description: The path to download and extract to. + required: true + default: "./" +runs: + using: "composite" + steps: + - name: Download Godot Artifact + uses: actions/download-artifact@v3 + with: + name: ${{ inputs.name }} + path: ${{ inputs.path }} diff --git a/.github/actions/godot-api-dump/action.yml b/.github/actions/godot-api-dump/action.yml new file mode 100644 index 000000000000..47b675ae99fc --- /dev/null +++ b/.github/actions/godot-api-dump/action.yml @@ -0,0 +1,24 @@ +name: Dump Godot API +description: Dump Godot API for GDExtension +inputs: + bin: + description: The path to the Godot executable + required: true +runs: + using: "composite" + steps: + # Dump GDExtension interface and API + - name: Dump GDExtension interface and API for godot-cpp build + shell: sh + run: | + ${{ inputs.bin }} --headless --dump-gdextension-interface --dump-extension-api + mkdir godot-api + cp -f gdextension_interface.h godot-api/ + cp -f extension_api.json godot-api/ + + - name: Upload API dump + uses: ./.github/actions/upload-artifact + with: + name: 'godot-api-dump' + path: './godot-api/*' + diff --git a/.github/actions/godot-cache/action.yml b/.github/actions/godot-cache/action.yml index 2d7afc8514b8..09ad2099cc3c 100644 --- a/.github/actions/godot-cache/action.yml +++ b/.github/actions/godot-cache/action.yml @@ -16,7 +16,20 @@ runs: with: path: ${{inputs.scons-cache}} key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} + + # We try to match an existing cache to restore from it. Each potential key is checked against + # all existing caches as a prefix. E.g. 'linux-template-minimal' would match any cache that + # starts with "linux-template-minimal", such as "linux-template-minimal-master-refs/heads/master-6588a4a29af1621086feac0117d5d4d37af957fd". + # + # We check these prefixes in this order: + # + # 1. The exact match, including the base branch, the commit reference, and the SHA hash of the commit. + # 2. A partial match for the same base branch and the same commit reference. + # 3. A partial match for the same base branch and the base branch commit reference. + # 4. A partial match for the same base branch only (not ideal, matches any PR with the same base branch). + restore-keys: | ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}} ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}} + ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-refs/heads/${{env.GODOT_BASE_BRANCH}} ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}} diff --git a/.github/actions/godot-converter-test/action.yml b/.github/actions/godot-converter-test/action.yml new file mode 100644 index 000000000000..919a76e69375 --- /dev/null +++ b/.github/actions/godot-converter-test/action.yml @@ -0,0 +1,18 @@ +name: Test Godot project converter +description: Test the Godot project converter. +inputs: + bin: + description: The path to the Godot executable + required: true +runs: + using: "composite" + steps: + - name: Test 3-to-4 conversion + shell: sh + run: | + mkdir converter_test + cd converter_test + touch project.godot + ../${{ inputs.bin }} --headless --validate-conversion-3to4 + cd .. + rm converter_test -rf diff --git a/.github/actions/godot-project-test/action.yml b/.github/actions/godot-project-test/action.yml new file mode 100644 index 000000000000..fd8c024a37df --- /dev/null +++ b/.github/actions/godot-project-test/action.yml @@ -0,0 +1,37 @@ +name: Test Godot project +description: Run the test Godot project. +inputs: + bin: + description: The path to the Godot executable + required: true +runs: + using: "composite" + steps: + # Download and extract zip archive with project, folder is renamed to be able to easy change used project + - name: Download test project + shell: sh + run: | + wget https://github.com/godotengine/regression-test-project/archive/4.0.zip + unzip 4.0.zip + mv "regression-test-project-4.0" "test_project" + + # Editor is quite complicated piece of software, so it is easy to introduce bug here. + + - name: Open and close editor (Vulkan) + shell: sh + run: | + xvfb-run ${{ inputs.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true + misc/scripts/check_ci_log.py sanitizers_log.txt + + - name: Open and close editor (GLES3) + shell: sh + run: | + DRI_PRIME=0 xvfb-run ${{ inputs.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true + misc/scripts/check_ci_log.py sanitizers_log.txt + + # Run test project + - name: Run project + shell: sh + run: | + xvfb-run ${{ inputs.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true + misc/scripts/check_ci_log.py sanitizers_log.txt diff --git a/.github/workflows/godot_cpp_test.yml b/.github/workflows/godot_cpp_test.yml new file mode 100644 index 000000000000..2051920f3071 --- /dev/null +++ b/.github/workflows/godot_cpp_test.yml @@ -0,0 +1,54 @@ +name: 🪲 Godot CPP +on: + workflow_call: + +# Global Settings +env: + # Used for the cache key, and godot-cpp checkout. Add version suffix to force clean build. + GODOT_BASE_BRANCH: master + +concurrency: + group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-cpp-tests + cancel-in-progress: true + +jobs: + godot-cpp-tests: + runs-on: "ubuntu-20.04" + name: "Build and test Godot CPP" + steps: + - uses: actions/checkout@v3 + + - name: Setup python and scons + uses: ./.github/actions/godot-deps + + # Checkout godot-cpp + - name: Checkout godot-cpp + uses: actions/checkout@v3 + with: + repository: godotengine/godot-cpp + ref: ${{ env.GODOT_BASE_BRANCH }} + submodules: 'recursive' + path: 'godot-cpp' + + # Download generated API dump + - name: Download GDExtension interface and API dump + uses: ./.github/actions/download-artifact + with: + name: 'godot-api-dump' + path: './godot-api' + + # Extract and override existing files with generated files + - name: Extract GDExtension interface and API dump + run: | + cp -f godot-api/gdextension_interface.h godot-cpp/gdextension/ + cp -f godot-api/extension_api.json godot-cpp/gdextension/ + + # TODO: Add caching to the scons build and store it for CI via the godot-cache + # action. + + # Build godot-cpp test extension + - name: Build godot-cpp test extension + run: | + cd godot-cpp/test + scons target=template_debug dev_build=yes + cd ../.. diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml index ac47967b265a..e5ab2fde4381 100644 --- a/.github/workflows/linux_builds.yml +++ b/.github/workflows/linux_builds.yml @@ -4,7 +4,7 @@ on: # Global Settings env: - # Used for the cache key, and godot-cpp checkout. Add version suffix to force clean build. + # Used for the cache key. Add version suffix to force clean build. GODOT_BASE_BRANCH: master SCONSFLAGS: verbose=yes warnings=extra werror=yes module_text_server_fb_enabled=yes DOTNET_NOLOGO: true @@ -25,53 +25,52 @@ jobs: - name: Editor w/ Mono (target=editor) cache-name: linux-editor-mono target: editor - tests: false # Disabled due freeze caused by mix Mono build and CI sconsflags: module_mono_enabled=yes - doc-test: true bin: "./bin/godot.linuxbsd.editor.x86_64.mono" build-mono: true + tests: false # Disabled due freeze caused by mix Mono build and CI + doc-test: true proj-conv: true + api-compat: true artifact: true - compat: true - name: Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold) cache-name: linux-editor-double-sanitizers target: editor - tests: true # Debug symbols disabled as they're huge on this build and we hit the 14 GB limit for runners. sconsflags: dev_build=yes scu_build=yes debug_symbols=no precision=double use_asan=yes use_ubsan=yes linker=gold - proj-test: true - # Can be turned off for PRs that intentionally break compat with godot-cpp, - # until both the upstream PR and the matching godot-cpp changes are merged. - godot-cpp-test: true bin: "./bin/godot.linuxbsd.editor.dev.double.x86_64.san" build-mono: false + tests: true + proj-test: true + # Generate an API dump for godot-cpp tests. + api-dump: true # Skip 2GiB artifact speeding up action. artifact: false - name: Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld) cache-name: linux-editor-llvm-sanitizers target: editor - tests: true sconsflags: dev_build=yes use_asan=yes use_ubsan=yes use_llvm=yes linker=lld bin: "./bin/godot.linuxbsd.editor.dev.x86_64.llvm.san" build-mono: false + tests: true # Skip 2GiB artifact speeding up action. artifact: false - name: Template w/ Mono (target=template_release) cache-name: linux-template-mono target: template_release - tests: false sconsflags: module_mono_enabled=yes build-mono: false + tests: false artifact: true - name: Minimal template (target=template_release, everything disabled) cache-name: linux-template-minimal target: template_release - tests: false sconsflags: modules_enabled_by_default=no disable_3d=yes disable_advanced_gui=yes deprecated=no minizip=no + tests: false artifact: true steps: @@ -127,6 +126,24 @@ jobs: run: | ./modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --godot-platform=linuxbsd + - name: Prepare artifact + if: ${{ matrix.artifact }} + run: | + strip bin/godot.* + chmod +x bin/godot.* + + - name: Upload artifact + uses: ./.github/actions/upload-artifact + if: ${{ matrix.artifact }} + with: + name: ${{ matrix.cache-name }} + + - name: Dump Godot API + uses: ./.github/actions/godot-api-dump + if: ${{ matrix.api-dump }} + with: + bin: ${{ matrix.bin }} + # Execute unit tests for the editor - name: Unit tests if: ${{ matrix.tests }} @@ -144,84 +161,22 @@ jobs: ${{ matrix.bin }} --doctool --headless 2>&1 > /dev/null || true git diff --color --exit-code && ! git ls-files --others --exclude-standard | sed -e 's/^/New doc file missing in PR: /' | grep 'xml$' - # Test 3.x -> 4.x project converter - - name: Test project converter - if: ${{ matrix.proj-conv }} - run: | - mkdir converter_test - cd converter_test - touch project.godot - ../${{ matrix.bin }} --headless --validate-conversion-3to4 - cd .. - rm converter_test -rf - - # Download and extract zip archive with project, folder is renamed to be able to easy change used project - - name: Download test project - if: ${{ matrix.proj-test }} - run: | - wget https://github.com/godotengine/regression-test-project/archive/4.0.zip - unzip 4.0.zip - mv "regression-test-project-4.0" "test_project" - - # Editor is quite complicated piece of software, so it is easy to introduce bug here - - name: Open and close editor (Vulkan) - if: ${{ matrix.proj-test }} - run: | - xvfb-run ${{ matrix.bin }} --audio-driver Dummy --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true - misc/scripts/check_ci_log.py sanitizers_log.txt - - - name: Open and close editor (GLES3) - if: ${{ matrix.proj-test }} - run: | - DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy --rendering-driver opengl3 --editor --quit --path test_project 2>&1 | tee sanitizers_log.txt || true - misc/scripts/check_ci_log.py sanitizers_log.txt - - # Run test project - - name: Run project - if: ${{ matrix.proj-test }} - run: | - xvfb-run ${{ matrix.bin }} 40 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true - misc/scripts/check_ci_log.py sanitizers_log.txt - - # Checkout godot-cpp - - name: Checkout godot-cpp - if: ${{ matrix.godot-cpp-test }} - uses: actions/checkout@v3 - with: - repository: godotengine/godot-cpp - ref: ${{ env.GODOT_BASE_BRANCH }} - submodules: 'recursive' - path: 'godot-cpp' - - # Dump GDExtension interface and API - - name: Dump GDExtension interface and API for godot-cpp build - if: ${{ matrix.godot-cpp-test }} - run: | - ${{ matrix.bin }} --headless --dump-gdextension-interface --dump-extension-api - cp -f gdextension_interface.h godot-cpp/gdextension/ - cp -f extension_api.json godot-cpp/gdextension/ - - # Build godot-cpp test extension - - name: Build godot-cpp test extension - if: ${{ matrix.godot-cpp-test }} - run: | - cd godot-cpp/test - scons target=template_debug dev_build=yes - cd ../.. - + # Check API backwards compatibility - name: Check for GDExtension compatibility - if: ${{ matrix.compat }} + if: ${{ matrix.api-compat }} run: | ./misc/scripts/validate_extension_api.sh "${{ matrix.bin }}" || true # don't fail the CI for now - - name: Prepare artifact - if: ${{ matrix.artifact }} - run: | - strip bin/godot.* - chmod +x bin/godot.* + # Download and run the test project + - name: Test Godot project + uses: ./.github/actions/godot-project-test + if: ${{ matrix.proj-test }} + with: + bin: ${{ matrix.bin }} - - name: Upload artifact - uses: ./.github/actions/upload-artifact - if: ${{ matrix.artifact }} + # Test the project converter + - name: Test project converter + uses: ./.github/actions/godot-converter-test + if: ${{ matrix.proj-conv }} with: - name: ${{ matrix.cache-name }} + bin: ${{ matrix.bin }} diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml index 6e0fbbf461b0..ae6f452bc2a3 100644 --- a/.github/workflows/macos_builds.yml +++ b/.github/workflows/macos_builds.yml @@ -56,14 +56,6 @@ jobs: target: ${{ matrix.target }} tests: ${{ matrix.tests }} - # Execute unit tests for the editor - - name: Unit tests - if: ${{ matrix.tests }} - run: | - ${{ matrix.bin }} --version - ${{ matrix.bin }} --help - ${{ matrix.bin }} --test - - name: Prepare artifact run: | strip bin/godot.* @@ -73,3 +65,11 @@ jobs: uses: ./.github/actions/upload-artifact with: name: ${{ matrix.cache-name }} + + # Execute unit tests for the editor + - name: Unit tests + if: ${{ matrix.tests }} + run: | + ${{ matrix.bin }} --version + ${{ matrix.bin }} --help + ${{ matrix.bin }} --test diff --git a/.github/workflows/runner.yml b/.github/workflows/runner.yml index be255b54688a..8e1741e844e3 100644 --- a/.github/workflows/runner.yml +++ b/.github/workflows/runner.yml @@ -6,10 +6,14 @@ concurrency: cancel-in-progress: true jobs: + # First stage: Only static checks, fast and prevent expensive builds from running. + static-checks: name: 📊 Static checks uses: ./.github/workflows/static_checks.yml + # Second stage: Run all the builds and some of the tests. + android-build: name: 🤖 Android needs: static-checks @@ -39,3 +43,15 @@ jobs: name: 🌐 Web needs: static-checks uses: ./.github/workflows/web_builds.yml + + # Third stage: Run auxiliary tests using build artifacts from previous jobs. + + # Can be turned off for PRs that intentionally break compat with godot-cpp, + # until both the upstream PR and the matching godot-cpp changes are merged. + godot-cpp-test: + name: 🪲 Godot CPP + # This can be changed to depend on another platform, if we decide to use it for + # godot-cpp instead. Make sure to move the .github/actions/godot-api-dump step + # appropriately. + needs: linux-build + uses: ./.github/workflows/godot_cpp_test.yml diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml index 182ae2fc8c41..ab62dca5cbca 100644 --- a/.github/workflows/windows_builds.yml +++ b/.github/workflows/windows_builds.yml @@ -60,14 +60,6 @@ jobs: target: ${{ matrix.target }} tests: ${{ matrix.tests }} - # Execute unit tests for the editor - - name: Unit tests - if: ${{ matrix.tests }} - run: | - ${{ matrix.bin }} --version - ${{ matrix.bin }} --help - ${{ matrix.bin }} --test - - name: Prepare artifact run: | Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force @@ -76,3 +68,11 @@ jobs: uses: ./.github/actions/upload-artifact with: name: ${{ matrix.cache-name }} + + # Execute unit tests for the editor + - name: Unit tests + if: ${{ matrix.tests }} + run: | + ${{ matrix.bin }} --version + ${{ matrix.bin }} --help + ${{ matrix.bin }} --test