gdam

THE GODOT ADDON MANAGER

Godot addons.
All in place.

One manifest for the addons your project needs. Exact GitHub Release tags. A single command to put everything where it belongs.

OPEN SOURCE / NO ACCOUNT TO INSTALL

YOUR PROJECT / DEPENDENCY MAP +
gdam.json Names + exact Release tags
↓ gdam install ↓
01 / ADDON gd-router v0.0.2
02 / ADDON gd-observe gd-v0.0.3
DESTINATION res://addons/ ✓

A SMALL TOOL. A TIDIER PROJECT.

Start with
your first addon.

Install the CLI, create a manifest in your Godot project, then add an addon from the registry.

Installation guide ↗
GODOT PROJECT / QUICK START ↗
curl -fsSL https://gdam.dev/install | sh

$ gdam init
created gdam.json

$ gdam add @aviorstudio/gd-router
installed @aviorstudio/gd-router@v0.0.2

$ gdam install
same manifest → same addon tags
ILLUSTRATIVE SESSION · MIT · LINUX, MACOS & WINDOWS

01 / PIN

Release tags stay explicit.

The manifest records exact, case-sensitive tags. Without a tag, gdam selects the newest stable Release.

02 / LINK

Room for local work.

Edit an addon next door. Its local path belongs in gdam.link.json, separate from the manifest you commit.

03 / PUBLISH

Your releases stay yours.

The registry points to GitHub Release assets. Publishing uses an owner-scoped secret key.

Two files, one job each

What ends up in your repo.

The session above wrote both of these. gdam.json is the one you commit: it records exact tags for gd-observe and gd-router, and lists gd-gesture with no tag because that addon is linked locally.

Where that link actually points lives in gdam.link.json — an absolute path on one machine, which is exactly the kind of thing that must never reach anyone else's checkout. Keeping the two apart is the whole reason there are two.

gdam.json commit this
{
  "addons": {
    "@aviorstudio/gd-gesture": {},
    "@aviorstudio/gd-observe": {
      "tag": "gd-v0.0.3"
    },
    "@aviorstudio/gd-router": {
      "tag": "v0.0.2"
    }
  }
}
gdam.link.json yours alone
{
  "addons": {
    "@aviorstudio/gd-gesture": {
      "enabled": true,
      "path": "/home/you/code/roguelike/gd-gesture"
    }
  }
}
Commands, GitHub Actions and download integrity

The whole command surface.

Nine commands, and three environment variables behind them: GDAM_API_URL to point the CLI at another registry, GDAM_SECRET_KEY to publish from CI, and an optional GITHUB_TOKEN when release downloads start hitting GitHub's rate limit.

Without a tag, gdam resolves the newest stable (non-prerelease) Release. Exact tags may select prereleases and are case-sensitive: Release-1 and release-1 are different.

- uses: aviorstudio/gdam-actions/install@v0.1.0
  with:
    version: v0.0.8

- uses: aviorstudio/gdam-actions/publish@v0.1.0
  with:
    tag: ${{ steps.release.outputs.tag }}
    asset: ${{ steps.release.outputs.asset }}
    secret-key: ${{ secrets.GDAM_SECRET_KEY }}

Exact release tags make the snippet readable and reproducible under the project's no-move policy, but Git tags can be moved or deleted. A Full 40-character commit SHA is the strongest GitHub Actions pin; use 15042aa1ff1e28f5e97828384b78a25c63d0199e when immutability is required.

What v0.0.8 enforces. Registry requests time out after 30 seconds and responses are limited to 4 MiB. Asset downloads use the immutable asset-ID endpoint, time out after two minutes, follow at most five redirects, remove authorization on a cross-origin redirect, and stop at 128 MiB. gdam checks the registered release, commit, asset identity and mandatory SHA-256 digest before extraction, and detects a truncated declared download. Extraction rejects absolute paths, .. traversal, backslashes and symlinks, with at most 10,000 entries and 512 MiB total uncompressed content. The resulting package root must contain plugin.cfg.

Command Does
gdam init Write gdam.json in this Godot project
gdam add @user/addon[@tag] Resolve it, install it, record its exact Release tag
gdam install Install every exact tag the manifest records
gdam remove @user/addon Take it out, and out of the manifest
gdam link @user/addon [path] Point it at a checkout on your disk
gdam unlink @user/addon Put the tagged release back
gdam unlink --all Undo every link at once
gdam publish @user/addon TAG [ASSET_NAME] Publish an exact Release tag and optional asset
gdam --version What is installed

PUT THE PIECES TOGETHER

One file in.
The same addons out.

Find your next addon ↗ Read the CLI guide ↗