Getting Your Extension Used
此内容尚不支持你的语言。
You have built and packed an extension. Where it goes next depends on who should be able to use it:
| Destination | Who sees it | Command |
|---|---|---|
| Local Designer | just you, on this machine | gtdx dev --once |
| The public store | anyone | gtdx login → gtdx publish --registry greentic-store |
| A tenant in Greentic Admin | one tenant’s users | gtdx component register |
They are not steps in a sequence — pick the one that matches your intent.
Local Designer
Section titled “Local Designer”The fastest loop, and what gtdx dev already does:
gtdx dev --once # build + pack + installgtdx install ./dist/my-ext-0.1.0.gtxpack -y # or install an existing packSign it, even locally. gtdx install accepts an unsigned pack without complaint, so
this looks like it worked — but the Designer refuses to load one, and says so only in its
own log:
failed to load extension greentic.my-ext-0.1.0:signature verification failed: missing signature fieldInstalling and being loaded are separate things, and only the second one is what you wanted. Sign as part of packing:
gtdx keygen --out my-key.pem # oncegtdx publish --sign --key my-key.pem # writes a signed pack to dist/gtdx install ./dist/my-ext-0.1.0.gtxpack -yIf it still does not show up, the cause is almost always version skew rather than a bad pack. See Designer Compatibility and the troubleshooting section of the Extension Quickstart.
Once it loads, it appears in /api/extensions:
curl -s localhost:<port>/api/extensions | grep my-ext# {"id":"greentic.my-ext","version":"0.1.0","kind":"design","enabled":true,"node_count":0}The public store
Section titled “The public store”Check the version slot first — reads are anonymous, so this needs no account and tells you immediately whether the version is free:
gtdx publish --verify-only --registry greentic-store# verify-only: greentic.my-ext@0.1.0 slot free in https://store.greentic.cloudThen authenticate and publish:
gtdx login # browser device flowgtdx publish --sign --key my-key.pem --registry greentic-storegtdx login also takes --no-browser (prints the URL and code), --paste (paste a token
by hand), and --token for CI. Publishing Extensions
covers signing keys, trust policies, and how the store verifies a pack.
A tenant in Greentic Admin
Section titled “A tenant in Greentic Admin”gtdx component register registers a component that is already published as a
component-tool for one tenant. It does not upload your extension — if you want the
artifact distributed, publish it to the store first, then register its URL here.
-
Postgres. Current Admin builds read Postgres for at least one module, so SQLite alone is not enough despite what
--dbdefaults to:Terminal window docker run -d --name gt-admin-pg \-e POSTGRES_USER=admin -e POSTGRES_PASSWORD=admin -e POSTGRES_DB=greentic_admin \-p 55432:5432 postgres:16-alpineexport GREENTIC_ADMIN_DB_PG="postgres://admin:admin@127.0.0.1:55432/greentic_admin"Without it, start-up fails with
GREENTIC_ADMIN_DB_PG is not set. -
Migrate and create an owner.
reset-adminalso needs the Postgres URL exported:Terminal window greentic-admin migrate --db "sqlite://./admin.db?mode=rwc"greentic-admin reset-admin --db "sqlite://./admin.db?mode=rwc" \--email owner@local.test --password '<password>' -
Start it.
Terminal window greentic-admin start --port 8090 --db "sqlite://./admin.db?mode=rwc" -
Log in and keep the CSRF token. State-changing calls use a double-submit token returned in the login body — not as a cookie:
Terminal window curl -s -c jar.txt -o login.json -X POST localhost:8090/api/admin/login \-H 'Content-Type: application/json' \-d '{"email":"owner@local.test","password":"<password>"}'CSRF=$(python3 -c "import json;print(json.load(open('login.json'))['csrf_token'])") -
Mint a service key. Owner-only, and the secret is returned exactly once:
Terminal window curl -s -b jar.txt -X POST localhost:8090/api/admin/service-keys \-H 'Content-Type: application/json' -H "x-csrf-token: $CSRF" \-d '{"label":"gtdx-local"}'# {"id":…,"prefix":"gts_…","label":"gtdx-local","key":"gts_…","created_at":…} -
Create a tenant, if you do not have one. A fresh Admin has none, and registering against a missing tenant fails with a bare
404 not found:Terminal window curl -s -b jar.txt -X POST localhost:8090/api/admin/tenants \-H 'Content-Type: application/json' -H "x-csrf-token: $CSRF" \-d '{"name":"Acme","slug":"acme"}' -
Register the component.
Terminal window gtdx component register \--url "oci://ghcr.io/org/component-demo@sha256:<digest>" \--name demo-tool \--tenant acme \--user owner@local.test \--admin-url http://localhost:8090 \--admin-token gts_…# ✓ registered component-tool 'demo-tool' (id=…) url=… roles=(default)--admin-tokenalso readsGREENTIC_ADMIN_TOKEN, or thegreentic-adminkey in~/.greentic/credentials.toml.--usermust be a tenant admin — it is sent asX-Greentic-Userand the tenant slug asX-Greentic-Tenant.
Confirm it landed:
curl -s -H "Authorization: Bearer gts_…" \ -H 'X-Greentic-Tenant: acme' -H 'X-Greentic-User: owner@local.test' \ localhost:8090/api/v1/designer/tenant/me/component-tools- Publishing Extensions — signing, trust policies, and store verification
- Designer Compatibility — why a built extension can be invisible
- Extension Quickstart — the whole path from install to publish