diff --git a/.github/scripts/godot_ci_cache.py b/.github/scripts/godot_ci_cache.py new file mode 100644 index 0000000..ef77335 --- /dev/null +++ b/.github/scripts/godot_ci_cache.py @@ -0,0 +1,79 @@ +# +# Fixes https://github.com/godotengine/godot/issues/77508 +# original script source: https://gist.github.com/d6e/5ed21c37a8ac294db26532cc6af5c61c +# + +import os +import subprocess +import time +import re +from pathlib import Path + +# Set the path to your Godot project and Godot executable +GODOT_PROJECT_PATH = Path(".") +GODOT_EXECUTABLE = "godot" # or the path to your Godot executable +GODOT_LOG_FILE = Path("artifacts") / "godot_output.log" # Log file to store Godot output + +print("Building godot cache...", flush=True) +start_time = time.time() + +# Step 1: Recursively find all '.import' files and collect the expected imported file paths +expected_imported_files = set() +for import_file in GODOT_PROJECT_PATH.rglob('*.import'): + content = import_file.read_text() + matches = re.findall(r'dest_files=\["(res://\.godot/imported/.+?)"\]', content) + expected_imported_files.update(matches) + +total_imports = len(expected_imported_files) +print(f"Found {total_imports} references to imported files...", flush=True) + +# Step 2: Launch Godot in the background to start the import process +print("Starting Godot to import files...", flush=True) +GODOT_LOG_FILE.parent.mkdir(parents=True, exist_ok=True) +with GODOT_LOG_FILE.open("w") as log_file: + try: + godot_process = subprocess.Popen( + [GODOT_EXECUTABLE, "--path", str(GODOT_PROJECT_PATH), "--editor", "--headless"], + stdout=log_file, + stderr=subprocess.STDOUT + ) + except Exception as e: + print(f"Failed to start Godot: {e}") + exit(1) + +# Step 3: Continually check if the expected imported files exist +imported_folder = GODOT_PROJECT_PATH / ".godot/imported" +while expected_imported_files: + # Wait until the imported directory exists + if not imported_folder.exists(): + print(f"Waiting for the imported directory to be created by Godot...") + time.sleep(1) + continue + + for expected_path in list(expected_imported_files): + imported_file_path = GODOT_PROJECT_PATH / expected_path.replace("res://", "") + if imported_file_path.exists(): + expected_imported_files.remove(expected_path) + imported_count = total_imports - len(expected_imported_files) + print(f"Imported {imported_count} / {total_imports} files...") + time.sleep(1) # Wait for a second before checking again + +elapsed_time = time.time() - start_time +print(f"Imported all files in {elapsed_time:.2f} seconds.", flush=True) + +# Step 4: Once all files have been imported, quit Godot +try: + print("Quitting Godot...", flush=True) + start_time = time.time() + godot_process.terminate() + godot_process.wait(timeout=10) + +except subprocess.TimeoutExpired: + print("Godot did not terminate in a timely manner; killing the process.") + godot_process.kill() +finally: + elapsed_time = time.time() - start_time + print(f"Godot has been closed in {elapsed_time:.2f} seconds.", flush=True) + +print("All files have been imported. Godot has been closed.") + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 185304b..ad2fe22 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,21 +9,60 @@ on: workflow_dispatch: jobs: - build-macos: - runs-on: macos-latest + build: + # Linux and Windows builds run on Ubuntu + runs-on: ${{ matrix.build == 'macos' && 'macos' || 'ubuntu' }}-latest + strategy: + fail-fast: false + matrix: + build: [macos, windows, linux] + include: + - build: linux + godot-bin: 'godot.linuxbsd.editor.x86_64.mono' + - build: macos + godot-bin: 'godot.macos.editor.universal' + # Windows build runs on Ubuntu + - build: windows + godot-bin: 'godot.linuxbsd.editor.x86_64.mono' + steps: - uses: actions/checkout@v3 - uses: chickensoft-games/setup-godot@v1 with: - version: 4.2.1 - use-dotnet: false + version: 4.2.2 + # When running on Linux, we have to use the .NET build, as this is + # the only custom build available from the CI + use-dotnet: ${{ matrix.build == 'linux' || matrix.build == 'windows' }} include-templates: true + - name: Download Godot w/Bitcoin module + uses: robinraju/release-downloader@v1.11 + with: + repository: LayerTwo-Labs/godot-bitcoin-module + tag: v4.2.2-bitcoin + filename: ${{ matrix.godot-bin }} + + # FIXME: remove + - name: show files + run: | + ls + #echo 'TEMPLATES' + #ls '/Users/runner/Library/Application Support/Godot/export_templates/4.2.2.stable' + #echo 'MACOS TEMPLATES' + #zipinfo -1 '/Users/runner/Library/Application Support/Godot/export_templates/4.2.2.stable/macos.zip' + #echo 'VERSION TXT' + #cat '/Users/runner/Library/Application Support/Godot/export_templates/4.2.2.stable/version.txt' + echo $GODOT + - name: Verify Setup run: | + chmod +x ${{ matrix.godot-bin }} + mv ${{ matrix.godot-bin }} $GODOT godot --version + - name: Import certificate to Keychain + if: ${{ matrix.build == 'macos' }} run: | echo "${{ secrets.MACOS_CERTIFICATE }}" | base64 --decode > certificate.p12 KEYCHAIN_PASSWORD=$(uuidgen) @@ -36,49 +75,14 @@ jobs: MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} - name: Setup notarization credentials + if: ${{ matrix.build == 'macos' }} run: | echo ${{ secrets.GODOT_MACOS_NOTARIZATION_API_KEY }} | base64 --decode > notarization_api_key.p8 - - name: Export build - run: | - godot --headless --export-debug "macOS" --verbose 2>&1 | tee build.log - env: - GODOT_MACOS_NOTARIZATION_API_KEY_ID: ${{ secrets.GODOT_MACOS_NOTARIZATION_API_KEY_ID }} - GODOT_MACOS_NOTARIZATION_API_KEY: ./notarization_api_key.p8 - GODOT_MACOS_NOTARIZATION_API_UUID: ${{ secrets.GODOT_MACOS_NOTARIZATION_API_UUID }} - - - name: Upload macOS build - uses: actions/upload-artifact@v4 - with: - name: drivechain_launcher_macos - if-no-files-found: error - path: build/drivechain_launcher-* - - - name: Wait for notarization to finish - run: | - request_id=$(grep 'Notarization request UUID' build.log | rev | cut -d ' ' -f 1 | rev | tr -d '"') - xcrun notarytool wait $request_id \ - --issuer ${{ secrets.GODOT_MACOS_NOTARIZATION_API_UUID }} \ - --key-id ${{ secrets.GODOT_MACOS_NOTARIZATION_API_KEY_ID }} \ - --key ./notarization_api_key.p8 - build-windows-linux: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - build: [windows, linux] - - steps: - - uses: actions/checkout@v3 - - uses: chickensoft-games/setup-godot@v1 - with: - version: 4.2.1 - use-dotnet: false - include-templates: true + # MUST be run before build + - name: Initialize godot cache + run: python3 .github/scripts/godot_ci_cache.py - - name: Verify Setup - run: | - godot --version - name: Export build run: | name="${{fromJSON('{"windows": "Windows Desktop", "linux": "Linux/X11"}')[matrix.build] }}"