Browse Source

CI: Partially sync workflows and actions with 3.x branch

Stick to `ubuntu:20.04` runners for now, as porting to newer ones implies
fixing a number of compilation warnings which may not be worth the trouble
for an EOL branch.
Rémi Verschelde 11 months ago
parent
commit
742eae5a2e
36 changed files with 665 additions and 472 deletions
  1. 38 0
      .github/actions/godot-build/action.yml
  2. 21 0
      .github/actions/godot-cache-restore/action.yml
  3. 17 0
      .github/actions/godot-cache-save/action.yml
  4. 27 0
      .github/actions/godot-deps/action.yml
  5. 19 0
      .github/actions/upload-artifact/action.yml
  6. 40 26
      .github/workflows/android_builds.yml
  7. 30 22
      .github/workflows/ios_builds.yml
  8. 31 38
      .github/workflows/javascript_builds.yml
  9. 123 63
      .github/workflows/linux_builds.yml
  10. 47 46
      .github/workflows/macos_builds.yml
  11. 46 0
      .github/workflows/runner.yml
  12. 48 68
      .github/workflows/server_builds.yml
  13. 17 16
      .github/workflows/static_checks.yml
  14. 55 51
      .github/workflows/windows_builds.yml
  15. 0 1
      compat.py
  16. 1 0
      core/core_builders.py
  17. 0 3
      doc/classes/@GlobalScope.xml
  18. 5 5
      doc/tools/makerst.py
  19. 1 0
      editor/editor_builders.py
  20. 1 0
      editor/icons/editor_icons_builders.py
  21. 2 1
      gles_builders.py
  22. 1 0
      main/main_builders.py
  23. 0 108
      misc/ci/android-tools-linux.sh
  24. 0 4
      misc/ci/sources.list
  25. 1 1
      misc/scripts/black_format.sh
  26. 53 0
      misc/scripts/check_ci_log.py
  27. 3 1
      misc/scripts/clang_format.sh
  28. 29 13
      misc/scripts/file_format.sh
  29. 1 0
      modules/gdnative/gdnative_builders.py
  30. 2 2
      modules/mono/doc_classes/CSharpScript.xml
  31. 1 1
      modules/mono/doc_classes/GodotSharp.xml
  32. 1 0
      platform/osx/platform_osx_builders.py
  33. 1 1
      platform/server/detect.py
  34. 1 0
      platform/windows/platform_windows_builders.py
  35. 1 1
      platform/x11/detect.py
  36. 1 0
      platform/x11/platform_x11_builders.py

+ 38 - 0
.github/actions/godot-build/action.yml

@@ -0,0 +1,38 @@
+name: Build Godot
+description: Build Godot with the provided options.
+inputs:
+  target:
+    description: The scons target (debug/release_debug/release).
+    default: "debug"
+  tools:
+    description: If tools are to be built.
+    default: false
+  tests:
+    description: If tests are to be built.
+    default: false
+  platform:
+    description: The Godot platform to build.
+    required: false
+  sconsflags:
+    default: ""
+  scons-cache:
+    description: The scons cache path.
+    default: "${{ github.workspace }}/.scons-cache/"
+  scons-cache-limit:
+    description: The scons cache size limit.
+    # actions/cache has 10 GiB limit, and GitHub runners have a 14 GiB disk.
+    # Limit to 7 GiB to avoid having the extracted cache fill the disk.
+    default: 7168
+runs:
+  using: "composite"
+  steps:
+    - name: Scons Build
+      shell: sh
+      env:
+          SCONSFLAGS: ${{ inputs.sconsflags }}
+          SCONS_CACHE: ${{ inputs.scons-cache }}
+          SCONS_CACHE_LIMIT: ${{ inputs.scons-cache-limit }}
+      run: |
+        echo "Building with flags:" ${{ env.SCONSFLAGS }}
+        scons p=${{ inputs.platform }} target=${{ inputs.target }} tools=${{ inputs.tools }} tests=${{ inputs.tests }} --jobs=2 ${{ env.SCONSFLAGS }}
+        ls -l bin/

+ 21 - 0
.github/actions/godot-cache-restore/action.yml

@@ -0,0 +1,21 @@
+name: Restore Godot build cache
+description: Restore Godot build cache.
+inputs:
+  cache-name:
+    description: The cache base name (job name by default).
+    default: "${{github.job}}"
+  scons-cache:
+    description: The scons cache path.
+    default: "${{github.workspace}}/.scons-cache/"
+runs:
+  using: "composite"
+  steps:
+    - name: Restore .scons_cache directory
+      uses: actions/cache/restore@v4
+      with:
+        path: ${{inputs.scons-cache}}
+        key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
+        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}}

+ 17 - 0
.github/actions/godot-cache-save/action.yml

@@ -0,0 +1,17 @@
+name: Save Godot build cache
+description: Save Godot build cache.
+inputs:
+  cache-name:
+    description: The cache base name (job name by default).
+    default: "${{github.job}}"
+  scons-cache:
+    description: The scons cache path.
+    default: "${{github.workspace}}/.scons-cache/"
+runs:
+  using: "composite"
+  steps:
+    - name: Save .scons_cache directory
+      uses: actions/cache/save@v4
+      with:
+        path: ${{inputs.scons-cache}}
+        key: ${{inputs.cache-name}}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}

+ 27 - 0
.github/actions/godot-deps/action.yml

@@ -0,0 +1,27 @@
+name: Setup python and scons
+description: Setup python, install the pip version of scons.
+inputs:
+  python-version:
+    description: The python version to use.
+    default: "3.x"
+  python-arch:
+    description: The python architecture.
+    default: "x64"
+runs:
+  using: "composite"
+  steps:
+    # Use python 3.x release (works cross platform)
+    - name: Set up Python 3.x
+      uses: actions/setup-python@v5
+      with:
+        # Semantic version range syntax or exact version of a Python version
+        python-version: ${{ inputs.python-version }}
+        # Optional - x64 or x86 architecture, defaults to x64
+        architecture: ${{ inputs.python-arch }}
+
+    - name: Setup scons
+      shell: bash
+      run: |
+        python -c "import sys; print(sys.version)"
+        python -m pip install scons==4.7.0
+        scons --version

+ 19 - 0
.github/actions/upload-artifact/action.yml

@@ -0,0 +1,19 @@
+name: Upload Godot artifact
+description: Upload the Godot artifact.
+inputs:
+  name:
+    description: The artifact name.
+    default: "${{ github.job }}"
+  path:
+    description: The path to upload.
+    required: true
+    default: "bin/*"
+runs:
+  using: "composite"
+  steps:
+    - name: Upload Godot Artifact
+      uses: actions/upload-artifact@v4
+      with:
+        name: ${{ inputs.name }}
+        path: ${{ inputs.path }}
+        retention-days: 14

+ 40 - 26
.github/workflows/android_builds.yml

@@ -1,32 +1,34 @@
 name: 🤖 Android Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
 env:
-  SCONSFLAGS: platform=android verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  SCONSFLAGS: verbose=yes warnings=all werror=yes debug_symbols=no
   ANDROID_HOME: /home/runner/work/godot/godot/android-sdk
   ANDROID_NDK_ROOT: /home/runner/work/godot/godot/android-sdk/ndk/21.1.6352462
   ANDROID_NDK_VERSION: 21.1.6352462
 
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-android
+  cancel-in-progress: true
+
 jobs:
   android-template:
     runs-on: "ubuntu-20.04"
-
     name: Template (target=release, tools=no)
 
     steps:
       - uses: actions/checkout@v4
 
-      # Azure repositories are not reliable, we need to prevent azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
-        run: |
-          sudo rm -f /etc/apt/sources.list.d/*
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
-          sudo apt-get update
-
       - name: Set up Java 8, Android SDK and NDK
         run: |
           # Not using actions/setup-java and android-actions/setup-android as I couldn't make them work for such old Java/SDK/NDK combination.
+          # Azure repositories are flaky, remove them.
+          sudo rm -f /etc/apt/sources.list.d/{azure,microsoft}*
+          sudo apt-get update
           sudo apt-get install openjdk-8-jdk
           sudo update-alternatives --set java /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
           mkdir -p ${{env.ANDROID_HOME}}
@@ -38,27 +40,39 @@ jobs:
           # https://github.com/godotengine/build-containers/blob/3.2/Dockerfile.android
           ./cmdline-tools/bin/sdkmanager --sdk_root=${{env.ANDROID_HOME}} 'build-tools;28.0.3' 'platforms;android-28' 'cmake;3.10.2.4988404' 'ndk;${{env.ANDROID_NDK_VERSION}}'
 
-      # Use python 3.x release (works cross platform)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
+        continue-on-error: true
+
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
+
+      - name: Compilation (armv7)
+        uses: ./.github/actions/godot-build
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+          sconsflags: ${{ env.SCONSFLAGS }} android_arch=armv7
+          platform: android
+          target: release
+          tools: false
 
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
+      - name: Compilation (arm64v8)
+        uses: ./.github/actions/godot-build
+        with:
+          sconsflags: ${{ env.SCONSFLAGS }} android_arch=arm64v8
+          platform: android
+          target: release
+          tools: false
+
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
+        continue-on-error: true
 
-      - name: Compilation
+      - name: Generate Godot templates
         run: |
-          scons target=release tools=no android_arch=armv7
-          scons target=release tools=no android_arch=arm64v8
           cd platform/android/java
           ./gradlew generateGodotTemplates
           cd ../../..
           ls -l bin/
+
+      - name: Upload artifact
+        uses: ./.github/actions/upload-artifact

+ 30 - 22
.github/workflows/ios_builds.yml

@@ -1,9 +1,17 @@
 name: 🍏 iOS Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
 env:
-  SCONSFLAGS: platform=iphone verbose=yes warnings=all werror=no debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  # iOS platform on this branch doesn't build without errors.
+  SCONSFLAGS: verbose=yes warnings=all werror=no debug_symbols=no
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-ios
+  cancel-in-progress: true
 
 jobs:
   ios-template:
@@ -13,24 +21,24 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
-      # Use python 3.x release (works cross platform)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
+        continue-on-error: true
+
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
+
+      - name: Compilation (arm64v8)
+        uses: ./.github/actions/godot-build
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
-
-      # You can test your matrix by printing the current Python version
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
-
-      - name: Compilation
-        run: |
-          scons target=release tools=no
-          ls -l bin/
+          sconsflags: ${{ env.SCONSFLAGS }}
+          platform: iphone
+          target: release
+          tools: false
+
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
+        continue-on-error: true
+
+      - name: Upload artifact
+        uses: ./.github/actions/upload-artifact

+ 31 - 38
.github/workflows/javascript_builds.yml

@@ -1,11 +1,18 @@
 name: 🌐 JavaScript Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
 env:
-  SCONSFLAGS: platform=javascript verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  SCONSFLAGS: verbose=yes warnings=all werror=yes debug_symbols=no
   EM_VERSION: 1.39.20
-  EM_CACHE_FOLDER: 'emsdk-cache'
+  EM_CACHE_FOLDER: "emsdk-cache"
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-javascript
+  cancel-in-progress: true
 
 jobs:
   javascript-template:
@@ -15,49 +22,35 @@ jobs:
     steps:
       - uses: actions/checkout@v4
 
-      # Azure repositories are not reliable, we need to prevent azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
-        run: |
-          sudo rm -f /etc/apt/sources.list.d/*
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
-          sudo apt-get update
-
-      # Additional cache for Emscripten generated system libraries
-      - name: Load Emscripten cache
-        id: javascript-template-emscripten-cache
-        uses: actions/cache@v4
-        with:
-          path: ${{env.EM_CACHE_FOLDER}}
-          key: ${{env.EM_VERSION}}-${{github.job}}
-
-      # Use python 3.x release (works cross platform)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
-        with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
-
-      # You can test your matrix by printing the current Python version
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
-
       - name: Set up Emscripten latest
         uses: mymindstorm/setup-emsdk@v14
         with:
           version: ${{env.EM_VERSION}}
           actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
+          cache-key: emsdk-${{ matrix.cache-name }}-${{env.GODOT_BASE_BRANCH}}-${{github.ref}}-${{github.sha}}
 
       - name: Verify Emscripten setup
         run: |
           emcc -v
 
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
+        continue-on-error: true
+
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
+
       - name: Compilation
-        run: |
-          scons target=release tools=no use_closure_compiler=yes
-          ls -l bin/
+        uses: ./.github/actions/godot-build
+        with:
+          sconsflags: ${{ env.SCONSFLAGS }}
+          platform: javascript
+          target: release
+          tools: false
+
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
+        continue-on-error: true
+
+      - name: Upload artifact
+        uses: ./.github/actions/upload-artifact

+ 123 - 63
.github/workflows/linux_builds.yml

@@ -1,94 +1,154 @@
 name: 🐧 Linux Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
 env:
-  SCONSFLAGS: platform=linuxbsd verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  SCONSFLAGS: verbose=yes warnings=all werror=yes
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-linux
+  cancel-in-progress: true
 
 jobs:
-  linux-editor-mono:
+  build-linux:
     runs-on: "ubuntu-20.04"
-    name: Editor w/ Mono (target=release_debug, tools=yes)
+    name: ${{ matrix.name }}
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - name: Editor w/ Mono (target=release_debug, tools=yes)
+            cache-name: linux-editor-mono
+            target: release_debug
+            tools: true
+            sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no
+            bin: "./bin/godot.x11.opt.tools.64.mono"
+            build-mono: true
+            artifact: true
+
+          - name: Editor and sanitizers (target=debug, tools=yes, use_asan=yes, use_ubsan=yes, linker=gold)
+            cache-name: linux-editor-sanitizers
+            target: debug
+            tools: true
+            sconsflags: use_asan=yes use_ubsan=yes linker=gold
+            test: true
+            bin: "./bin/godot.x11.tools.64s"
+            build-mono: false
+            # Skip 2GiB artifact speeding up action.
+            artifact: false
+
+          - name: Template w/ Mono (target=release, tools=no)
+            cache-name: linux-template-mono
+            target: release
+            tools: false
+            sconsflags: module_mono_enabled=yes mono_static=yes mono_glue=no debug_symbols=no
+            build-mono: false
+            artifact: true
 
     steps:
       - uses: actions/checkout@v4
 
-      # Azure repositories are not reliable, we need to prevent azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
+      - name: Linux dependencies
+        shell: bash
         run: |
-          sudo rm -f /etc/apt/sources.list.d/*
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
+          # Azure repositories are flaky, remove them.
+          sudo rm -f /etc/apt/sources.list.d/{azure,microsoft}*
           sudo apt-get update
+          # The actual dependencies.
+          sudo apt-get install --no-install-recommends build-essential pkg-config libx11-dev \
+              libxcursor-dev libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev \
+              libpulse-dev libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm xvfb wget unzip
 
-      # Install all packages (except scons)
-      - name: Configure dependencies
+      - name: Free disk space on runner
         run: |
-          sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev xvfb \
-            libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
+          echo "Disk usage before:" && df -h
+          sudo rm -rf /usr/local/lib/android
+          echo "Disk usage after:" && df -h
 
-      # Use python 3.x release (works cross platform; best to keep self contained in it's own step)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-      # Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
+
+      - name: Setup GCC problem matcher
+        uses: ammaraskar/gcc-problem-matcher@master
 
-      # We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
       - name: Compilation
-        run: |
-          scons tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
-          xvfb-run ./bin/godot.x11.opt.tools.64.mono --generate-mono-glue modules/mono/glue || true
-          scons tools=yes target=release_debug module_mono_enabled=yes mono_glue=yes
-          ls -l bin/
+        uses: ./.github/actions/godot-build
+        with:
+          sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
+          platform: linuxbsd
+          target: ${{ matrix.target }}
+          tools: ${{ matrix.tools }}
 
-  linux-template-mono:
-    runs-on: "ubuntu-20.04"
-    name: Template w/ Mono (target=release, tools=no)
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
+        with:
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-    steps:
-      - uses: actions/checkout@v4
+      # Generate mono glue
+      - name: Generate Mono glue code
+        if: ${{ matrix.build-mono }}
+        run: |
+          DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --generate-mono-glue modules/mono/glue || true
 
-      # Azure repositories are not reliable, we need to prevent azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
+      # Rebuild with mono
+      - name: Compilation (mono_glue=yes)
+        uses: ./.github/actions/godot-build
+        if: ${{ matrix.build-mono }}
+        with:
+          sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }} mono_glue=yes
+          platform: linuxbsd
+          target: ${{ matrix.target }}
+          tools: ${{ matrix.tools }}
+
+      # Download and extract zip archive with project, folder is renamed to be able to easy change used project
+      - name: Download test project
+        if: ${{ matrix.test }}
         run: |
-          sudo rm -f /etc/apt/sources.list.d/*
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
-          sudo apt-get update
+          wget https://github.com/godotengine/regression-test-project/archive/3.2.zip
+          unzip 3.2.zip
+          mv "regression-test-project-3.2" "test_project"
 
-      # Install all packages (except scons)
-      - name: Configure dependencies
+      # Editor is quite complicated piece of software, so it is easy to introduce bug here
+      - name: Open and close editor
+        if: ${{ matrix.test }}
         run: |
-          sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
-            libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
+          DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --audio-driver Dummy -e -q --path test_project 2>&1 | tee sanitizers_log.txt || true
+          misc/scripts/check_ci_log.py sanitizers_log.txt
 
-      # Use python 3.x release (works cross platform)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
-        with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+      # Run test project
+      - name: Run project
+        if: ${{ matrix.test }}
+        run: |
+          DRI_PRIME=0 xvfb-run ${{ matrix.bin }} 30 --video-driver GLES3 --audio-driver Dummy --path test_project 2>&1 | tee sanitizers_log.txt || true
+          misc/scripts/check_ci_log.py sanitizers_log.txt
 
-      # You can test your matrix by printing the current Python version
-      - name: Configuring Python packages
+      # Check class reference
+      - name: Check for class reference updates
+        if: ${{ matrix.test }}
         run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
+          echo "Running --doctool to see if this changes the public API without updating the documentation."
+          echo -e "If a diff is shown, it means that your code/doc changes are incomplete and you should update the class reference with --doctool.\n\n"
+          DRI_PRIME=0 xvfb-run ${{ matrix.bin }} --doctool . 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$'
 
-      - name: Compilation
+      - name: Prepare artifact
+        if: ${{ matrix.artifact }}
         run: |
-          scons target=release tools=no module_mono_enabled=yes mono_glue=no
-          ls -l bin/
+          strip bin/godot.*
+          chmod +x bin/godot.*
+
+      - name: Upload artifact
+        uses: ./.github/actions/upload-artifact
+        if: ${{ matrix.artifact }}
+        with:
+          name: ${{ matrix.cache-name }}

+ 47 - 46
.github/workflows/macos_builds.yml

@@ -1,67 +1,68 @@
 name: 🍎 macOS Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
 env:
-  SCONSFLAGS: platform=osx verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  SCONSFLAGS: verbose=yes warnings=all werror=yes debug_symbols=no
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macos
+  cancel-in-progress: true
 
 jobs:
-  macos-editor:
+  build-macos:
     runs-on: "macos-latest"
+    name: ${{ matrix.name }}
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - name: Editor (target=release_debug, tools=yes)
+            cache-name: macos-editor
+            target: release_debug
+            tools: true
+            bin: "./bin/godot.osx.opt.tools.64"
 
-    name: Editor (target=release_debug, tools=yes)
+          - name: Template (target=release, tools=no)
+            cache-name: macos-template
+            target: release
+            tools: false
 
     steps:
       - uses: actions/checkout@v4
 
-      # Use python 3.x release (works cross platform; best to keep self contained in it's own step)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-      # Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
 
-      # We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
       - name: Compilation
-        run: |
-          scons tools=yes target=release_debug
-          ls -l bin/
-
-  macos-template:
-    runs-on: "macos-latest"
-    name: Template (target=release, tools=no)
-
-    steps:
-      - uses: actions/checkout@v4
+        uses: ./.github/actions/godot-build
+        with:
+          sconsflags: ${{ env.SCONSFLAGS }}
+          platform: osx
+          target: ${{ matrix.target }}
+          tools: ${{ matrix.tools }}
 
-      # Use python 3.x release (works cross platform)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-      # You can test your matrix by printing the current Python version
-      - name: Configuring Python packages
+      - name: Prepare artifact
         run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
+          strip bin/godot.*
+          chmod +x bin/godot.*
 
-      - name: Compilation
-        run: |
-          scons target=release tools=no
-          ls -l bin/
+      - name: Upload artifact
+        uses: ./.github/actions/upload-artifact
+        with:
+          name: ${{ matrix.cache-name }}

+ 46 - 0
.github/workflows/runner.yml

@@ -0,0 +1,46 @@
+name: 🔗 GHA
+on: [push, pull_request]
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-runner
+  cancel-in-progress: true
+
+jobs:
+  static-checks:
+    name: 📊 Static
+    uses: ./.github/workflows/static_checks.yml
+
+  android-build:
+    name: 🤖 Android
+    needs: static-checks
+    uses: ./.github/workflows/android_builds.yml
+
+  ios-build:
+    name: 🍏 iOS
+    needs: static-checks
+    uses: ./.github/workflows/ios_builds.yml
+
+  javascript-build:
+    name: 🌐 JavaScript
+    needs: static-checks
+    uses: ./.github/workflows/javascript_builds.yml
+
+  linux-build:
+    name: 🐧 Linux
+    needs: static-checks
+    uses: ./.github/workflows/linux_builds.yml
+
+  macos-build:
+    name: 🍎 macOS
+    needs: static-checks
+    uses: ./.github/workflows/macos_builds.yml
+
+  server-build:
+    name: ☁ Server
+    needs: static-checks
+    uses: ./.github/workflows/server_builds.yml
+
+  windows-build:
+    name: 🏁 Windows
+    needs: static-checks
+    uses: ./.github/workflows/windows_builds.yml

+ 48 - 68
.github/workflows/server_builds.yml

@@ -1,88 +1,68 @@
 name: ☁ Server Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
 env:
-  SCONSFLAGS: platform=server verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  SCONSFLAGS: verbose=yes warnings=all werror=yes debug_symbols=no module_mono_enabled=yes mono_static=yes mono_glue=no
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-server
+  cancel-in-progress: true
 
 jobs:
-  linux-editor:
+  build-server:
     runs-on: "ubuntu-20.04"
-    name: Linux Headless w/ Mono (target=release_debug, tools=yes)
+    name: ${{ matrix.name }}
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - name: Linux Headless w/ Mono (target=release_debug, tools=yes)
+            cache-name: server-editor-mono
+            target: release_debug
+            tools: true
+
+          - name: Linux Server w/ Mono (target=release, tools=no)
+            cache-name: server-template-mono
+            target: release
+            tools: false
 
     steps:
       - uses: actions/checkout@v4
 
-      # Azure repositories are not reliable, we need to prevent azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
+      - name: Linux dependencies
+        shell: bash
         run: |
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
+          # Azure repositories are flaky, remove them.
+          sudo rm -f /etc/apt/sources.list.d/{azure,microsoft}*
           sudo apt-get update
+          # The actual dependencies.
+          sudo apt-get install --no-install-recommends build-essential pkg-config libx11-dev \
+              libxcursor-dev libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev \
+              libpulse-dev libdbus-1-dev libudev-dev libxi-dev libxrandr-dev yasm xvfb wget unzip
 
-      # Install all packages (except scons)
-      - name: Configure dependencies
-        run: |
-          sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
-            libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
-
-      # Use python 3.x release (works cross platform; best to keep self contained in it's own step)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-      # Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
 
-      # We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
       - name: Compilation
-        run: |
-          scons -j2 verbose=yes warnings=all werror=yes platform=server tools=yes target=release_debug module_mono_enabled=yes mono_glue=no
-
-  linux-server:
-    runs-on: "ubuntu-20.04"
-    name: Linux Server w/ Mono (target=release, tools=no)
-
-    steps:
-      - uses: actions/checkout@v4
-
-      # Azure repositories are not reliable, we need to prevent azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
-        run: |
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
-          sudo apt-get update
-
-      # Install all packages (except scons)
-      - name: Configure dependencies
-        run: |
-          sudo apt-get install build-essential pkg-config libx11-dev libxcursor-dev \
-            libxinerama-dev libgl1-mesa-dev libglu-dev libasound2-dev libpulse-dev libudev-dev libxi-dev libxrandr-dev yasm
-
-      # Use python 3.x release (works cross platform)
-      - name: Set up Python 3.x
-        uses: actions/setup-python@v5
+        uses: ./.github/actions/godot-build
         with:
-          # Semantic version range syntax or exact version of a Python version
-          python-version: '3.x'
-          # Optional - x64 or x86 architecture, defaults to x64
-          architecture: 'x64'
+          sconsflags: ${{ env.SCONSFLAGS }} ${{ matrix.sconsflags }}
+          platform: server
+          target: ${{ matrix.target }}
+          tools: ${{ matrix.tools }}
 
-      # You can test your matrix by printing the current Python version
-      - name: Configuring Python packages
-        run: |
-          python -c "import sys; print(sys.version)"
-          python -m pip install scons
-          python --version
-          scons --version
-
-      - name: Compilation
-        run: |
-          scons -j2 target=release tools=no module_mono_enabled=yes mono_glue=no
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
+        with:
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true

+ 17 - 16
.github/workflows/static_checks.yml

@@ -1,36 +1,33 @@
 name: 📊 Static Checks
-on: [push, pull_request]
+on:
+  workflow_call:
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
+  cancel-in-progress: true
 
 jobs:
   static-checks:
     name: Static Checks (clang-format, black format, file format, documentation checks)
-    runs-on: ubuntu-20.04
+    runs-on: "ubuntu-20.04"
     steps:
       - name: Checkout
         uses: actions/checkout@v4
 
-      # Azure repositories are not reliable, we need to prevent Azure giving us packages.
-      - name: Make apt sources.list use the default Ubuntu repositories
-        run: |
-          sudo rm -f /etc/apt/sources.list.d/*
-          sudo cp -f misc/ci/sources.list /etc/apt/sources.list
-          sudo apt-get update
-
       - name: Install dependencies
         run: |
-          sudo apt-get install -qq dos2unix recode clang-format-10
-          sudo update-alternatives --remove-all clang-format
+          # Azure repositories are flaky, remove them.
+          sudo rm -f /etc/apt/sources.list.d/{azure,microsoft}*
+          sudo apt-get update
+          sudo apt-get install -qq dos2unix python3-pip moreutils
+          sudo update-alternatives --remove-all clang-format || true
           sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-10 100
-          sudo pip3 install black==20.8b1 pygments
+          sudo pip3 install black==24.8.0 pygments
 
       - name: File formatting checks (file_format.sh)
         run: |
           bash ./misc/scripts/file_format.sh
 
-      - name: Style checks via clang-format (clang_format.sh)
-        run: |
-          bash ./misc/scripts/clang_format.sh
-
       - name: Python style checks via black (black_format.sh)
         run: |
           bash ./misc/scripts/black_format.sh
@@ -38,3 +35,7 @@ jobs:
       - name: Documentation checks
         run: |
           doc/tools/makerst.py --dry-run doc/classes modules
+
+      - name: Style checks via clang-format (clang_format.sh)
+        run: |
+          bash ./misc/scripts/clang_format.sh

+ 55 - 51
.github/workflows/windows_builds.yml

@@ -1,69 +1,73 @@
 name: 🏁 Windows Builds
-on: [push, pull_request]
+on:
+  workflow_call:
 
 # Global Settings
+# SCONS_CACHE for windows must be set in the build environment
 env:
-  SCONSFLAGS: platform=windows verbose=yes warnings=all werror=yes debug_symbols=no --jobs=2
+  # Only used for the cache key. Increment version to force clean build.
+  GODOT_BASE_BRANCH: 3.2
+  SCONSFLAGS: verbose=yes warnings=all werror=yes debug_symbols=no
+  SCONS_CACHE_MSVC_CONFIG: true
+
+concurrency:
+  group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-windows
+  cancel-in-progress: true
 
 jobs:
-  windows-editor:
+  build-windows:
     # Windows 10 with latest image
     runs-on: "windows-latest"
+    name: ${{ matrix.name }}
+    strategy:
+      fail-fast: false
+      matrix:
+        include:
+          - name: Editor (target=release_debug, tools=yes)
+            cache-name: windows-editor
+            target: release_debug
+            tools: true
+            bin: "./bin/godot.windows.opt.tools.64.exe"
 
-    # Windows Editor - checkout with the plugin
-    name: Editor (target=release_debug, tools=yes)
+          - name: Template (target=release, tools=no)
+            cache-name: windows-template
+            target: release
+            tools: false
 
     steps:
-    - uses: actions/checkout@v4
-
-    # Use python 3.x release (works cross platform; best to keep self contained in it's own step)
-    - name: Set up Python 3.x
-      uses: actions/setup-python@v5
-      with:
-        # Semantic version range syntax or exact version of a Python version
-        python-version: '3.x'
-        # Optional - x64 or x86 architecture, defaults to x64
-        architecture: 'x64'
+      - uses: actions/checkout@v4
 
-    # Setup scons, print python version and scons version info, so if anything is broken it won't run the build.
-    - name: Configuring Python packages
-      run: |
-        python -c "import sys; print(sys.version)"
-        python -m pip install scons pywin32
-        python --version
-        scons --version
+      - name: Restore Godot build cache
+        uses: ./.github/actions/godot-cache-restore
+        with:
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-    # We should always be explicit with our flags usage here since it's gonna be sure to always set those flags
-    - name: Compilation
-      run: |
-        scons tools=yes target=release_debug
-        ls -l bin/
+      - name: Setup python and scons
+        uses: ./.github/actions/godot-deps
 
-  windows-template:
-    runs-on: "windows-latest"
-    name: Template (target=release, tools=no)
+      - name: Setup MSVC problem matcher
+        uses: ammaraskar/msvc-problem-matcher@master
 
-    steps:
-    - uses: actions/checkout@v4
+      - name: Compilation
+        uses: ./.github/actions/godot-build
+        with:
+          sconsflags: ${{ env.SCONSFLAGS }}
+          platform: windows
+          target: ${{ matrix.target }}
+          tools: ${{ matrix.tools }}
 
-    # Use python 3.x release (works cross platform)
-    - name: Set up Python 3.x
-      uses: actions/setup-python@v5
-      with:
-        # Semantic version range syntax or exact version of a Python version
-        python-version: '3.x'
-        # Optional - x64 or x86 architecture, defaults to x64
-        architecture: 'x64'
+      - name: Save Godot build cache
+        uses: ./.github/actions/godot-cache-save
+        with:
+          cache-name: ${{ matrix.cache-name }}
+        continue-on-error: true
 
-    # You can test your matrix by printing the current Python version
-    - name: Configuring Python packages
-      run: |
-        python -c "import sys; print(sys.version)"
-        python -m pip install scons pywin32
-        python --version
-        scons --version
+      - name: Prepare artifact
+        run: |
+          Remove-Item bin/* -Include *.exp,*.lib,*.pdb -Force
 
-    - name: Compilation
-      run: |
-        scons target=release tools=no
-        ls -l bin/
+      - name: Upload artifact
+        uses: ./.github/actions/upload-artifact
+        with:
+          name: ${{ matrix.cache-name }}

+ 0 - 1
compat.py

@@ -43,7 +43,6 @@ if sys.version_info < (3,):
         # Not properly equivalent to __qualname__ in py3, but it doesn't matter.
         return obj.__name__
 
-
 else:
 
     def isbasestring(s):

+ 1 - 0
core/core_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 from platform_methods import subprocess_main
 from compat import iteritems, itervalues, open_utf8, escape_string, byte_to_str
 

+ 0 - 3
doc/classes/@GlobalScope.xml

@@ -30,9 +30,6 @@
 		<member name="Geometry" type="Geometry" setter="" getter="">
 			The [Geometry] singleton.
 		</member>
-		<member name="GodotSharp" type="GodotSharp" setter="" getter="">
-			The [GodotSharp] singleton.
-		</member>
 		<member name="IP" type="IP" setter="" getter="">
 			The [IP] singleton.
 		</member>

+ 5 - 5
doc/tools/makerst.py

@@ -584,7 +584,7 @@ def escape_rst(text, until_pos=-1):  # type: (str) -> str
         pos = text.find("*", pos, until_pos)
         if pos == -1:
             break
-        text = text[:pos] + "\*" + text[pos + 1 :]
+        text = text[:pos] + "\\*" + text[pos + 1 :]
         pos += 2
 
     # Escape _ character at the end of a word to avoid interpreting it as an inline hyperlink
@@ -594,7 +594,7 @@ def escape_rst(text, until_pos=-1):  # type: (str) -> str
         if pos == -1:
             break
         if not text[pos + 1].isalnum():  # don't escape within a snake_case word
-            text = text[:pos] + "\_" + text[pos + 1 :]
+            text = text[:pos] + "\\_" + text[pos + 1 :]
             pos += 2
         else:
             pos += 1
@@ -852,7 +852,7 @@ def rstize_text(text, state):  # type: (str, State) -> str
 
         # Properly escape things like `[Node]s`
         if escape_post and post_text and (post_text[0].isalnum() or post_text[0] == "("):  # not punctuation, escape
-            post_text = "\ " + post_text
+            post_text = "\\ " + post_text
 
         next_brac_pos = post_text.find("[", 0)
         iter_pos = 0
@@ -860,7 +860,7 @@ def rstize_text(text, state):  # type: (str, State) -> str
             iter_pos = post_text.find("*", iter_pos, next_brac_pos)
             if iter_pos == -1:
                 break
-            post_text = post_text[:iter_pos] + "\*" + post_text[iter_pos + 1 :]
+            post_text = post_text[:iter_pos] + "\\*" + post_text[iter_pos + 1 :]
             iter_pos += 2
 
         iter_pos = 0
@@ -869,7 +869,7 @@ def rstize_text(text, state):  # type: (str, State) -> str
             if iter_pos == -1:
                 break
             if not post_text[iter_pos + 1].isalnum():  # don't escape within a snake_case word
-                post_text = post_text[:iter_pos] + "\_" + post_text[iter_pos + 1 :]
+                post_text = post_text[:iter_pos] + "\\_" + post_text[iter_pos + 1 :]
                 iter_pos += 2
             else:
                 iter_pos += 1

+ 1 - 0
editor/editor_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 import os
 import os.path
 from platform_methods import subprocess_main

+ 1 - 0
editor/icons/editor_icons_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 import os
 from platform_methods import subprocess_main
 from compat import StringIO

+ 2 - 1
gles_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 from platform_methods import subprocess_main
 
 
@@ -385,7 +386,7 @@ def build_legacygl_header(filename, include, class_suffix, output_attribs, gles2
             x = header_data.enums[xv]
             bits = 1
             amt = len(x)
-            while 2 ** bits < amt:
+            while 2**bits < amt:
                 bits += 1
             strs = "{"
             for i in range(amt):

+ 1 - 0
main/main_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 from platform_methods import subprocess_main
 from compat import byte_to_str
 from collections import OrderedDict

+ 0 - 108
misc/ci/android-tools-linux.sh

@@ -1,108 +0,0 @@
-#!/bin/bash
-
-# SDK
-# https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip
-# SHA-256 444e22ce8ca0f67353bda4b85175ed3731cae3ffa695ca18119cbacef1c1bea0
-# latest version available here: https://developer.android.com/studio/index.html
-
-# NDK
-# https://dl.google.com/android/repository/android-ndk-r15c-linux-x86_64.zip
-# SHA-1 0bf02d4e8b85fd770fd7b9b2cdec57f9441f27a2
-# latest version available here: https://developer.android.com/ndk/downloads/index.html
-
-BASH_RC=~/.bashrc
-GODOT_BUILD_TOOLS_PATH=./godot-dev/build-tools
-mkdir -p $GODOT_BUILD_TOOLS_PATH
-cd $GODOT_BUILD_TOOLS_PATH
-
-ANDROID_BASE_URL=http://dl.google.com/android/repository
-
-ANDROID_SDK_RELEASE=4333796
-ANDROID_SDK_DIR=android-sdk
-ANDROID_SDK_FILENAME=sdk-tools-linux-$ANDROID_SDK_RELEASE.zip
-ANDROID_SDK_URL=$ANDROID_BASE_URL/$ANDROID_SDK_FILENAME
-ANDROID_SDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_SDK_DIR
-ANDROID_SDK_SHA256=92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9
-
-ANDROID_NDK_RELEASE=r21
-ANDROID_NDK_DIR=android-ndk
-ANDROID_NDK_FILENAME=android-ndk-$ANDROID_NDK_RELEASE-linux-x86_64.zip
-ANDROID_NDK_URL=$ANDROID_BASE_URL/$ANDROID_NDK_FILENAME
-ANDROID_NDK_PATH=$GODOT_BUILD_TOOLS_PATH/$ANDROID_NDK_DIR
-ANDROID_NDK_SHA1=afc9c0b9faad222898ac8168c78ad4ccac8a1b5c
-
-echo
-echo "Download and install Android development tools ..."
-echo
-
-if [ ! -e $ANDROID_SDK_FILENAME ]; then
-  echo "Downloading: Android SDK ..."
-  curl -L -O $ANDROID_SDK_URL
-else
-  echo $ANDROID_SDK_SHA1 $ANDROID_SDK_FILENAME > $ANDROID_SDK_FILENAME.sha1
-  if [ $(shasum -a 256 < $ANDROID_SDK_FILENAME | awk '{print $1;}') != $ANDROID_SDK_SHA1 ]; then
-    echo "Downloading: Android SDK ..."
-    curl -L -O $ANDROID_SDK_URL
-  fi
-fi
-
-if [ ! -d $ANDROID_SDK_DIR ]; then
-  echo "Extracting: Android SDK ..."
-  unzip -qq $ANDROID_SDK_FILENAME -d $ANDROID_SDK_DIR
-  echo
-fi
-
-if [ ! -e $ANDROID_NDK_FILENAME ]; then
-  echo "Downloading: Android NDK ..."
-  curl -L -O $ANDROID_NDK_URL
-else
-  echo $ANDROID_NDK_MD5 $ANDROID_NDK_FILENAME > $ANDROID_NDK_FILENAME.md5
-  if [ $(shasum -a 1 < $ANDROID_NDK_FILENAME | awk '{print $1;}') != $ANDROID_NDK_SHA1 ]; then
-    echo "Downloading: Android NDK ..."
-    curl -L -O $ANDROID_NDK_URL
-  fi
-fi
-
-if [ ! -d $ANDROID_NDK_DIR ]; then
-  echo "Extracting: Android NDK ..."
-  unzip -qq $ANDROID_NDK_FILENAME
-  mv android-ndk-$ANDROID_NDK_RELEASE $ANDROID_NDK_DIR
-  echo
-fi
-
-mkdir -p ~/.android && echo "count=0" > ~/.android/repositories.cfg
-echo "Installing: Accepting Licenses ..."
-yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager --licenses > /dev/null
-echo "Installing: Android Build and Platform Tools ..."
-yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'tools' > /dev/null
-yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'platform-tools' > /dev/null
-yes | $ANDROID_SDK_DIR/tools/bin/sdkmanager 'build-tools;29.0.3' > /dev/null
-echo
-
-EXPORT_VAL="export ANDROID_HOME=$ANDROID_SDK_PATH"
-if ! grep -q "^$EXPORT_VAL" $BASH_RC; then
-        echo $EXPORT_VAL >> $BASH_RC
-fi
-#eval $EXPORT_VAL
-
-EXPORT_VAL="export ANDROID_NDK_ROOT=$ANDROID_NDK_PATH"
-if ! grep -q "^$EXPORT_VAL" $BASH_RC; then
-        echo $EXPORT_VAL >> $BASH_RC
-fi
-#eval $EXPORT_VAL
-
-EXPORT_VAL="export PATH=$PATH:$ANDROID_SDK_PATH/tools"
-if ! grep -q "^export PATH=.*$ANDROID_SDK_PATH/tools.*" $BASH_RC; then
-        echo $EXPORT_VAL >> $BASH_RC
-fi
-#eval $EXPORT_VAL
-
-EXPORT_VAL="export PATH=$PATH:$ANDROID_SDK_PATH/tools/bin"
-if ! grep -q "^export PATH=.*$ANDROID_SDK_PATH/tools/bin.*" $BASH_RC; then
-        echo $EXPORT_VAL >> $BASH_RC
-fi
-#eval $EXPORT_VAL
-
-echo
-echo "Done!"
-echo

+ 0 - 4
misc/ci/sources.list

@@ -1,4 +0,0 @@
-deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse
-deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse
-deb http://archive.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse
-deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse

+ 1 - 1
misc/scripts/black_format.sh

@@ -15,7 +15,7 @@ PY_FILES=$(find \( -path "./.git" \
                 \) -print)
 black -l 120 $PY_FILES
 
-git diff > patch.patch
+git diff --color > patch.patch
 
 # If no patch has been generated all is OK, clean up, and exit.
 if [ ! -s patch.patch ] ; then

+ 53 - 0
misc/scripts/check_ci_log.py

@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import sys
+
+if len(sys.argv) < 2:
+    print("ERROR: You must run program with file name as argument.")
+    sys.exit(1)
+
+fname = sys.argv[1]
+
+fileread = open(fname.strip(), "r")
+file_contents = fileread.read()
+
+# If find "ERROR: AddressSanitizer:", then happens invalid read or write
+# This is critical bug, so we need to fix this as fast as possible
+
+if file_contents.find("ERROR: AddressSanitizer:") != -1:
+    print("FATAL ERROR: An incorrectly used memory was found.")
+    sys.exit(1)
+
+# There is also possible, that program crashed with or without backtrace.
+
+if (
+    file_contents.find("Program crashed with signal") != -1
+    or file_contents.find("Dumping the backtrace") != -1
+    or file_contents.find("Segmentation fault (core dumped)") != -1
+    or file_contents.find("Aborted (core dumped)") != -1
+    or file_contents.find("terminate called without an active exception") != -1
+):
+    print("FATAL ERROR: Godot has been crashed.")
+    sys.exit(1)
+
+# Finding memory leaks in Godot is quite difficult, because we need to take into
+# account leaks also in external libraries. They are usually provided without
+# debugging symbols, so the leak report from it usually has only 2/3 lines,
+# so searching for 5 element - "#4 0x" - should correctly detect the vast
+# majority of memory leaks
+
+if file_contents.find("ERROR: LeakSanitizer:") != -1:
+    if file_contents.find("#4 0x") != -1:
+        print("ERROR: Memory leak was found")
+        sys.exit(1)
+
+# It may happen that Godot detects leaking nodes/resources and removes them, so
+# this possibility should also be handled as a potential error, even if
+# LeakSanitizer doesn't report anything
+
+if file_contents.find("ObjectDB instances leaked at exit") != -1:
+    print("ERROR: Memory leak was found")
+    sys.exit(1)
+
+sys.exit(0)

+ 3 - 1
misc/scripts/clang_format.sh

@@ -16,6 +16,8 @@ while IFS= read -rd '' f; do
         continue
     elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then
         continue
+    elif [[ "$f" == *"-so_wrap."* ]]; then
+        continue
     fi
 
     for extension in ${CLANG_FORMAT_FILE_EXTS[@]}; do
@@ -38,7 +40,7 @@ while IFS= read -rd '' f; do
     done
 done
 
-git diff > patch.patch
+git diff --color > patch.patch
 
 # If no patch has been generated all is OK, clean up, and exit.
 if [ ! -s patch.patch ] ; then

+ 29 - 13
misc/scripts/file_format.sh

@@ -5,8 +5,8 @@
 # run before them.
 
 # We need dos2unix and recode.
-if [ ! -x "$(command -v dos2unix)" -o ! -x "$(command -v recode)" ]; then
-    printf "Install 'dos2unix' and 'recode' to use this script.\n"
+if [ ! -x "$(command -v dos2unix)" -o ! -x "$(command -v isutf8)" ]; then
+    printf "Install 'dos2unix' and 'isutf8' (from the moreutils package) to use this script.\n"
 fi
 
 set -uo pipefail
@@ -20,19 +20,25 @@ while IFS= read -rd '' f; do
         continue
     elif [[ "$f" == *"sln" ]]; then
         continue
+    elif [[ "$f" == *".bat" ]]; then
+        continue
     elif [[ "$f" == *"patch" ]]; then
         continue
     elif [[ "$f" == *"pot" ]]; then
         continue
     elif [[ "$f" == *"po" ]]; then
         continue
-    elif [[ "$f" == "thirdparty"* ]]; then
+    elif [[ "$f" == "thirdparty/"* ]]; then
+        continue
+    elif [[ "$f" == *"/thirdparty/"* ]]; then
         continue
     elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then
         continue
+    elif [[ "$f" == *"-so_wrap."* ]]; then
+        continue
     fi
     # Ensure that files are UTF-8 formatted.
-    recode UTF-8 "$f" 2> /dev/null
+    isutf8 "$f" >> utf8-validation.txt 2>&1
     # Ensure that files have LF line endings and do not contain a BOM.
     dos2unix "$f" 2> /dev/null
     # Remove trailing space characters and ensures that files end
@@ -42,19 +48,29 @@ while IFS= read -rd '' f; do
     perl -i -pe 's/\x20== true//g' "$f"
 done
 
-git diff > patch.patch
+git diff --color > patch.patch
 
-# If no patch has been generated all is OK, clean up, and exit.
-if [ ! -s patch.patch ] ; then
+# If no UTF-8 violations were collected and no patch has been
+# generated all is OK, clean up, and exit.
+if [ ! -s utf8-validation.txt ] && [ ! -s patch.patch ] ; then
     printf "Files in this commit comply with the formatting rules.\n"
-    rm -f patch.patch
+    rm -f patch.patch utf8-validation.txt
     exit 0
 fi
 
-# A patch has been created, notify the user, clean up, and exit.
-printf "\n*** The following differences were found between the code "
-printf "and the formatting rules:\n\n"
-cat patch.patch
+# Violations detected, notify the user, clean up, and exit.
+if [ -s utf8-validation.txt ]
+then
+    printf "\n*** The following files contain invalid UTF-8 character sequences:\n\n"
+    cat utf8-validation.txt
+fi
+
+if [ -s patch.patch ]
+then
+    printf "\n*** The following differences were found between the code "
+    printf "and the formatting rules:\n\n"
+    cat patch.patch
+fi
+rm -f utf8-validation.txt patch.patch
 printf "\n*** Aborting, please fix your commit(s) with 'git commit --amend' or 'git rebase -i <hash>'\n"
-rm -f patch.patch
 exit 1

+ 1 - 0
modules/gdnative/gdnative_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 import json
 from platform_methods import subprocess_main
 

+ 2 - 2
modules/mono/doc_classes/CSharpScript.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<class name="CSharpScript" inherits="Script" category="Core" version="3.2">
+<class name="CSharpScript" inherits="Script" version="3.2">
 	<brief_description>
 		A script implemented in the C# programming language (Mono-enabled builds only).
 	</brief_description>
@@ -12,7 +12,7 @@
 	</tutorials>
 	<methods>
 		<method name="new" qualifiers="vararg">
-			<return type="Object">
+			<return type="Variant">
 			</return>
 			<description>
 				Returns a new instance of the script.

+ 1 - 1
modules/mono/doc_classes/GodotSharp.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<class name="GodotSharp" inherits="Object" category="Core" version="3.2">
+<class name="GodotSharp" inherits="Object" version="3.2">
 	<brief_description>
 		Bridge between Godot and the Mono runtime (Mono-enabled builds only).
 	</brief_description>

+ 1 - 0
platform/osx/platform_osx_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 import os
 from platform_methods import subprocess_main
 

+ 1 - 1
platform/server/detect.py

@@ -83,7 +83,7 @@ def configure(env):
 
     ## Architecture
 
-    is64 = sys.maxsize > 2 ** 32
+    is64 = sys.maxsize > 2**32
     if env["bits"] == "default":
         env["bits"] = "64" if is64 else "32"
 

+ 1 - 0
platform/windows/platform_windows_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 import os
 from platform_methods import subprocess_main
 

+ 1 - 1
platform/x11/detect.py

@@ -114,7 +114,7 @@ def configure(env):
 
     ## Architecture
 
-    is64 = sys.maxsize > 2 ** 32
+    is64 = sys.maxsize > 2**32
     if env["bits"] == "default":
         env["bits"] = "64" if is64 else "32"
 

+ 1 - 0
platform/x11/platform_x11_builders.py

@@ -3,6 +3,7 @@
 All such functions are invoked in a subprocess on Windows to prevent build flakiness.
 
 """
+
 import os
 from platform_methods import subprocess_main