Skip to content

Latest commit

 

History

History
443 lines (315 loc) · 16.8 KB

File metadata and controls

443 lines (315 loc) · 16.8 KB

Contributing Guide

Building SDK

Sentry SDK for Godot Engine can be built for Windows x86_64, Linux x86_64, macOS universal, and Android platforms. Support for more platforms and architectures are expected to be added in time.

Prerequisites

  • C/C++ compiler
  • SCons build tool and Python
  • CMake -- to build sentry-native SDK
  • clang-format & pre-commit -- for style checks
  • Android Studio -- to build supporting library for Android
  • .NET SDK 8.0 or later -- to build the .NET layer

On Windows, if you have scoop installed, you can easily install most of the required packages with the following command:

scoop install python scons cmake clang

You can also use an existing Python installation to install SCons build tool:

# install scons
python -m pip install scons

# upgrade scons
python -m pip install --upgrade scons

Or, on a Mac:

brew install scons

Compiling

  1. Clone this repository

  2. Restore submodules: git submodule update --init --recursive

  3. Build GDExtension libraries:

    # build *editor* library for the current platform
    # run from the repository root dir
    scons debug_symbols=yes

    The build process should produce a GDExtension library file for the editor target at project/addons/sentry/bin/....

    To export a project in Godot that uses this extension, you'll also need the libraries for the export templates:

    # build *export* library for the current platform
    scons debug_symbols=yes
  4. Open demo project in Godot Engine:

    # open demo project in Godot
    godot project/project.godot

In the Godot editor, you can adjust the Sentry SDK settings by going to Project Settings -> Sentry -> Config.

Android

Building Android targets requires Android Studio. Additionally, you need to assemble the SentryAndroidGodotPlugin library for Android builds:

./gradlew assemble

To build Android targets:

scons debug_symbols=yes platform=android

You can perform both steps by adding build_android_lib=yes option to scons command:

scons debug_symbols=yes platform=android build_android_lib=yes

iOS

Building for iOS requires making separate builds for device and simulator architectures, then combining them into an XCFramework using the generate_ios_framework=yes option:

scons platform=ios arch=arm64 ios_simulator=no
scons platform=ios arch=universal ios_simulator=yes generate_ios_framework=yes

Web

Building for Web requires Node.js to bundle the JavaScript bridge. First, install dependencies:

cd src/sentry/javascript/bridge
npm install

Then build the GDExtension library and generate the JavaScript bundle:

scons platform=web generate_js_bundle=yes

Or, build the JavaScript bundle separately:

scons js_bundle

You can also use npm scripts directly from the src/sentry/javascript/bridge directory:

npm run build          # Build production bundle to dist/
npm run build:deploy   # Build and copy to project/addons/sentry/web/
npm run clean          # Clean build artifacts
npm test               # Run tests

.NET Layer

The .NET layer source lives at src/sentry/dotnet/managed/. Building it stages compiled artifacts into project/addons/sentry/dotnet/lib/, which is what ships in the addon.

To build everything (.NET libraries + tests + demo project) via the dev solution at the repo root:

dotnet build

This picks up Sentry.Godot.slnx automatically.

The .NET layer auto-generates a passthrough delegation from Sentry.Godot.SentrySdk to the upstream Sentry.SentrySdk via a Roslyn source generator. To inspect the generated file:

dotnet build src/sentry/dotnet/managed/Sentry.Godot/Sentry.Godot.csproj /p:EmitCompilerGeneratedFiles=true /p:CompilerGeneratedFilesOutputPath=/tmp/gen

Project Structure

  • src/ -- Godot extension source code
  • src/sentry/dotnet/ -- C++ side of the .NET layer
  • src/sentry/dotnet/managed/ -- C# side of the .NET layer
  • modules/ -- various submodules, such as godot-cpp and other SDKs like sentry-native
  • project/ -- example Godot project
  • project/addons/sentry/ -- where build artifacts are placed
  • project/addons/sentry/dotnet/ -- shipped .NET addon files (Sentry.Godot.props, lib/, autoload glue)
  • project/test/ -- GDScript unit and integration tests for exported APIs, using gdUnit4
  • scripts/ -- various scripts used mostly for maintenance
  • assetlib/ -- metadata for Godot Asset Library entries
  • doc_classes/ -- built-in Godot documentation (class reference)
  • android_lib/ -- supporting library for Android, containing a Godot plugin that bridges the Sentry GDExtension with the native Sentry Android SDK.
  • tests/cpp/ -- C++/GDExtension tests
  • tests/dotnet/ -- .NET layer tests
  • tests/integration/ -- end-to-end integration tests using Pester and app-runner
  • tests/web/ -- Playwright-based web/WASM test infrastructure

Initialization Flow

Sentry for Godot consists of two layers: a native GDExtension and a managed C# library (loaded only in Godot's .NET edition with C# scripts). Initialization can be triggered from either layer. The diagram below shows the three expected initialization scenarios; dashed steps are reached only when managed .NET assemblies are loaded.

Scenario A: Automatic Initialization (Auto Init setting)

flowchart LR
    A1["Native auto-inits early"] --> A2["C# assembly loads"] --> A3["C# auto-inits, syncing options from native"]
    classDef dashed stroke-dasharray: 5 5
    class A2,A3 dashed
Loading

Scenario B: Initialized manually from GDScript

flowchart LR
    B1["GDScript calls init"] --> B2["GDScript config callback"] --> B3["Native inits"] --> B4["C# inits, syncing options from native"]
    classDef dashed stroke-dasharray: 5 5
    class B4 dashed
Loading

Scenario C: Initialized manually from C#

flowchart LR
    C1["C# calls init"] --> C2["C# config callback, syncing defaults from native"] --> C3["Native inits, syncing options from C# layer"] --> C4["C# inits"]
    classDef dashed stroke-dasharray: 5 5
    class C2,C4 dashed
Loading

Formatting Code

Please run clang-format before submitting a PR to adhere to our code style. C# files are formatted with dotnet format instead. Both run via pre-commit hooks for automatic formatting on commit:

pre-commit install

Documentation

Sentry documentation

We maintain official documentation in https://github.com/getsentry/sentry-docs. This is our main documentation. New features and changes should be reflected in that repository in a linked PR. See Contributing to Docs.

Built-in documentation

We also maintain a built-in Godot class reference. It is available offline right inside Godot editor. Each of the classes we export begins with "Sentry", so it's easy to find our API using the Search Help dialog. This documentation is located in the doc_classes/ directory, with each class stored in a corresponding XML file. The structure of these files is auto-generated, while the documentation text itself is added manually.

If you add or modify the public API, regenerate these files first, then fill in the text:

scripts/update-doc-classes.ps1

Compile the library with target=editor for your platform beforehand, or your changes will not be detected. Run the script again once you are done writing, as it corrects some style issues automatically.

Testing

🛈 Our CI automatically runs tests for open PRs.

Export Presets

Pre-configured export presets for testing are shipped in exports/export_presets.cfg. To use them, copy the file into the project/ directory (or merge with your existing presets):

cp exports/export_presets.cfg project/export_presets.cfg

Available presets:

  • Android Tests — Android debug export with Gradle build and GDExtension support
  • iOS Tests — iOS debug export with custom templates
  • Web Tests — Web debug export with threads and GDExtension support

Local Tests

Testing is performed using the gdUnit4 testing framework in GDScript. Unit tests (and other types of tests) are located in the project/test/ directory. These tests can be executed from the Godot editor, except for isolated tests (see below).

Some tests require isolation, meaning they need specific options to be set and must be executed in a separate process. These tests are located in the project/test/isolated/ directory.

To run the full desktop test set, use the following script:

pwsh scripts/run-desktop-tests.ps1

It runs the suites from project/test/suites/ and each isolated test in separate Godot processes. Set the GODOT environment variable if the engine is not in PATH.

For the Android platform, you can also run supporting Android library tests:

./gradlew test

C++ Unit Tests

Internal C++ code is covered by doctest running inside a headless Godot. Tests live in tests/cpp/tests/. Build with tests=yes and pass --test-sentry:

scons tests=yes
godot --headless --path project/ --editor --test-sentry

Forward doctest flags after --test-sentry, e.g. --test-suite="CsprojPatcher" to filter, or --dt-help for options.

.NET Tests

The Roslyn source generator that produces the Sentry.Godot.SentrySdk facade is covered by a snapshot test in tests/dotnet/Sentry.Godot.SourceGenerators.Tests/. Run it with:

dotnet test tests/dotnet/Sentry.Godot.SourceGenerators.Tests

When the generator output changes intentionally, accept the new baseline with:

pwsh scripts/accept-dotnet-snapshots.ps1

The script regenerates the *.received.txt file, promotes it over the existing *.verified.txt, and re-runs the tests to confirm the promoted baseline matches. Commit the updated *.verified.txt alongside the change that caused the drift.

Web Tests

Web tests run the same GDScript suite and isolated tests in a headless Chromium browser using Playwright. They require a Godot web export.

First-time setup

  1. Install the JavaScript bridge dependencies, if you have not already (see Web above):
    cd src/sentry/javascript/bridge
    npm install
  2. Copy the export preset into the project. Godot reads project/export_presets.cfg, but that path is gitignored and the preset is versioned under exports/:
    cp exports/export_presets.cfg project/export_presets.cfg
  3. Place the dlink web export templates for your Godot version in exports/templates/, where the preset expects them:
    mkdir -p exports/templates
    cp <godot-export-templates>/web_dlink_debug.zip <godot-export-templates>/web_dlink_release.zip exports/templates/
  4. Install the test dependencies:
    cd tests/web
    npm install
    npx playwright install chromium

Building the libraries

Web tests need two GDExtension builds: the web library that runs in the browser, and an editor library for your own platform, which provides export plugins. Repeat these only when the C++ or JavaScript bridge sources change.

The generated godot-cpp bindings are specific to one architecture and are not regenerated automatically when you switch, so each build is preceded by a clean.

  1. Build the web library and the JavaScript bundle. The "Web Tests" preset exports in debug mode with thread support, so build the debug, threaded variant:
    scons platform=web arch=wasm32 threads=yes generate_js_bundle=yes --clean
    scons platform=web arch=wasm32 threads=yes generate_js_bundle=yes
  2. Build the editor library for your own platform:
    scons debug_symbols=yes --clean
    scons debug_symbols=yes

Running Tests

Re-export the project after any change to the libraries or to anything under project/, then run the tests:

mkdir -p exports/web
godot --headless --path project --export-debug "Web Tests" ../exports/web/index.html
cd tests/web
npx playwright test

Or use the convenience PowerShell script (handles dependency installation automatically):

pwsh scripts/run-web-tests.ps1

By default, tests expect the web export in exports/web/. To use a different location, set the WEB_EXPORT_DIR environment variable:

WEB_EXPORT_DIR=path/to/export npx playwright test

End-to-End Integration Tests

Integration tests validate end-to-end SDK functionality by running test actions and verifying events are captured in Sentry. Tests are located in tests/integration/ and use PowerShell with Pester testing framework alongside the app-runner submodule.

Prerequisites

Install Pester PowerShell module:

Install-Module -Name Pester -Force -SkipPublisherCheck

Environment Variables

Required:

  • SENTRY_AUTH_TOKEN: Sentry API token for retrieving and validating events

Optional:

  • SENTRY_TEST_PLATFORM: Target platform, such as Linux, macOS, Windows, or Adb (see the app-runner submodule)
  • SENTRY_TEST_DEVICE: Device identifier for the selected provider, such as an ADB serial
  • SENTRY_TEST_DSN: Sentry project DSN where test events will be sent (defaults to reading from project.godot)
  • SENTRY_TEST_EXECUTABLE: Path to test executable (defaults to $env:GODOT)

Sauce Labs:

  • SAUCE_USERNAME: Sauce Labs username for authentication
  • SAUCE_ACCESS_KEY: Sauce Labs access key for authentication
  • SAUCE_REGION: Sauce Labs region (e.g., us-west-1)
  • SAUCE_DEVICE_NAME: Target device for testing (e.g., Samsung_Galaxy_S23_15_real_sjc1)
  • SAUCE_SESSION_NAME: Session identifier (e.g., Godot E2E Tests)

Running Tests

cd tests/integration
Invoke-Pester -Path Integration.Tests.ps1

Tests validate crash capture, message capture, runtime error capture, and event metadata. Results are saved to tests/integration/results/.

Run on a local Android device

Install the matching Godot Android export templates, configure the Android SDK and Java 17 in Godot, and connect an unlocked device with USB debugging enabled. Confirm that ADB reports it as authorized:

adb devices

Set the API token and run the local Android integration-test script from the repository root:

$env:SENTRY_AUTH_TOKEN = "<token>"
pwsh scripts/run-android-integration-tests.ps1

The script exports exports/android.apk, selects the only online ADB device, and runs the GDScript integration suite through the app-runner AdbProvider. Select the .NET suite or both suites with -Suite:

$env:GODOT = "/path/to/godot"
$env:GODOT_DOTNET = "/path/to/godot-dotnet"
pwsh scripts/run-android-integration-tests.ps1 -Suite Dotnet
pwsh scripts/run-android-integration-tests.ps1 -Suite All

GODOT may point to either a standard or .NET Godot executable. When it points to a .NET build, the script builds project/Sentry demo project.csproj before exporting the GDScript suite and verifies that the Android APK contains the Mono runtime.

The Dotnet mode requires the dotnet CLI, a Godot .NET executable, and matching Mono Android export templates. The All mode uses GODOT to export and run the GDScript suite first, then builds the project and uses GODOT_DOTNET to export and run the .NET suite.

If more than one device is online, select one by its ADB serial:

pwsh scripts/run-android-integration-tests.ps1 -DeviceSerial "<serial>"

An emulator uses the same path. Start it separately, wait until adb devices reports it as device, then pass its serial to the script. For example, this starts the first configured AVD without a window:

emulator -avd "$(emulator -list-avds | head -n 1)" \
  -no-window \
  -no-snapshot-save \
  -gpu swiftshader_indirect \
  -noaudio \
  -no-boot-anim \
  -camera-back none \
  -camera-front none

The integration-test script does not start or stop the emulator.

Releasing

Godot Asset Library

The Godot Asset Library entry is updated automatically via the publish-assetlib workflow, which runs when a GitHub Release is published. It extracts the version from SConstruct, resolves the download URL from the release assets, and submits an edit to the AssetLib API. Pre-release versions (containing - in the version string) are skipped automatically.

Asset metadata is stored in assetlib/addon.yaml. Changes to the AssetLib entry (title, description, icon, etc.) should be made through PRs updating this file.

You can test the update script locally using --dry-run:

./scripts/publish-assetlib.sh --dry-run assetlib/addon.yaml 1.3.0 4.3