Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Latest commit

History

25,435 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

GitW3

GitW3 is MetaState's self-hosted Git forge. It is a fork of Forgejo, rebranded for the MetaState / W3DS ecosystem.

Relationship to Forgejo

GitW3 tracks Forgejo releases. Everything that makes GitW3 GitW3 is deliberately confined to a thin layer on top of upstream:

  • Branding — application name, logo, colour scheme, templates and locale strings. Applied by branding/apply.sh, which rewrites upstream files in the working tree immediately before make build. Those rewrites are never committed, so the tracked diff against Forgejo stays empty. Forgejo's own custom/ mechanism cannot do this job: the Docker image points GITEA_CUSTOM at a volume, so the repository's custom/ directory is never read in a container, and the assets that need overriding are embedded into the binary at build time by the bindata tag anyway.
  • Nothing else, for now. In particular, W3DS login is not implemented in this fork. It is provided by a separate OIDC bridge service and wired up through Forgejo's built-in OAuth2 authentication sources, so it needs no change to this codebase.

Keeping the patch surface near zero is the whole strategy. Every line we diverge from upstream is a line that can conflict when the next Forgejo security release has to be merged.

Note that the Go module path is forgejo.org and the built binary is named gitea upstream. We override the binary name at build time (EXECUTABLE=gitw3) and leave both alone in the source — renaming them for real would mean touching thousands of lines for no user-visible gain.

Branches

BranchOwnerPurpose
mainusGitW3. Branched from upstream v16.0.2; carries our commits.
forgejoupstreamForgejo's development branch, mirrored verbatim. Do not commit here.
v*/forgejoupstreamForgejo release branches, mirrored verbatim. Do not commit here.
v* (tags)upstreamForgejo release tags, mirrored verbatim.
gitw3-v* (tags)usGitW3 releases.

Upstream refs are refreshed daily by .github/workflows/upstream-sync.yml, which only ever writes to upstream-owned refs and never to main.

Keeping up with upstream

See docs/gitw3/upstream-sync.md for the merge procedure.

This is not optional maintenance. Forgejo ships security releases regularly — v16.0.2 and v15.0.6 both landed on 2026-07-30 — and an un-upgraded forge exposed to the internet is a liability.

Building

Requires Go (version pinned in go.mod) and Node (pinned in .node-version).

make deps-frontend
./branding/apply.sh
EXECUTABLE=gitw3 TAGS="bindata sqlite sqlite_unlock_notify" make build
./gitw3 --version
git checkout -- cmd/ docker/ modules/ options/ public/ routers/ services/ templates/ web_src/

The branding step is not optional: without it make build produces a binary that still calls itself Forgejo. The last line puts the working tree back — see branding/README.md.

Container images are published to ghcr.io/ensombl/gitw3.

Local development

For iterating on code, use the live-reload dev server instead of the full build above:

make deps-frontend
TAGS="sqlite sqlite_unlock_notify" GITEA_RUN_MODE=dev make watch

make watch runs the frontend (webpack --watch) and backend (air, which rebuilds and restarts on .go/.tmpl changes) together. TAGS must be set explicitly here and include sqlite: unlike the release build above, make watch's backend target does not set it, so without it the install wizard won't offer SQLite3 as a database option.

First run serves the install wizard at http://localhost:3000. If that port is taken, set [server] HTTP_PORT in custom/conf/app.ini — environment variable overrides (GITEA__server__HTTP_PORT) are not read this early, only app.ini is. SQLite needs no other setup.

Testing W3DS login locally

GitW3 owns an always-visible Continue with W3DS button and the stable /user/login/w3ds entry point. The cryptographic wallet flow remains in the separate w3ds-oidc-bridge implemented by the MetaState team in MetaState-Prototype-Project/prototype#1102. The bridge is wired into Forgejo as an OAuth2 authentication source named exactly W3DS; GitW3 keeps the native button visible and reports a clear configuration error when that source is absent.

To exercise the complete flow locally:

  1. Run the OIDC bridge service (out of scope for this repo) and note its client ID, client secret, and .well-known/openid-configuration discovery URL.
  2. Register it as an authentication source. The name must be exactly W3DS — it's baked into the bridge's redirect URI as <ROOT_URL>/user/oauth2/W3DS/callback:
    ./gitea admin auth add-oauth \
    --name "W3DS" \
    --provider "openidConnect" \
    --key "<client id>" \
    --secret "<client secret>" \
    --auto-discover-url "http://<bridge-host>/.well-known/openid-configuration" \
    --scopes "openid" --scopes "profile" --scopes "email"
    The profile/email scopes are needed so Forgejo gets a real username/email back instead of falling back to the OIDC sub claim and a synthetic @w3ds.invalid address.
  3. Add the following to custom/conf/app.ini and restart (app.ini is only read at process startup, so this needs a restart of make watch, not just a hot-reload):
    [oauth2_client]ENABLE_AUTO_REGISTRATION = true
    ACCOUNT_LINKING = login
    USERNAME = nickname
    REGISTER_EMAIL_CONFIRM = false
    Without ENABLE_AUTO_REGISTRATION, Forgejo shows a manual "Complete new account" step on every first-time OAuth2 login instead of silently provisioning the account, which is the intended production behaviour.

Testing code sync locally

Code sync isn't part of this codebase either — a separate forgejo-code-sync service resolves each push's author via the W3DS link above and writes their commits into their eVault, using a Forgejo system webhook and the admin Users API. To exercise it locally:

  1. Create a dedicated site-admin service account for the sync service — not a shared human admin's login, since its token can read every account's login_name and every private repo's content.
  2. Generate two PATs on that account:
    • read:user,read:repository scopes, for the service's continuous use (FORGEJO_ADMIN_TOKEN).
    • write:admin scope, for the one-time webhook registration below (FORGEJO_PROVISIONING_TOKEN) — optional, falls back to the token above, but keeps the always-running token's blast radius smaller.
  3. If the sync service's webhook URL resolves to loopback relative to this instance (true for local dev, not for a real deployment), add the following to custom/conf/app.ini and restart:
    [webhook]ALLOWED_HOST_LIST = loopback
  4. Run the sync service's registration script once (idempotent, safe to re-run on redeploy) to register the system webhook via POST /api/v1/admin/hooks.
  5. Two things about that endpoint worth knowing, even though the script already handles both:
    • active must be sent as true explicitly — it defaults to false, and a hook created without it looks completely normal (201, listed in Site Administration) but never delivers anything.
    • config.is_system_webhook must be the literal string "true" — omit it and GitW3 silently creates a "default" webhook instead: invisible to GET /admin/hooks, and it only applies to repos created after it's added, never retroactively to existing ones.
    • Rotating the webhook secret needs the hook deleted and recreated, not PATCHed — PATCH /admin/hooks/{id} silently ignores a changed config.secret.
  6. Verify after registering: Site Administration → Webhooks shows the hook with Active on, not just present, and a "Test Delivery" (or a real push) actually reaches the service.
  7. Don't register the webhook twice — two system webhooks pointed at the same URL produce two envelopes per push; the sync service has no deduplication for that case by design.

Platform onboarding and Marketplace publication

The New action now offers guided W3DS platform creation. New-platform repositories receive a versioned .w3ds/platform.json, optional browser-generated identity keys, and the documented W3DS AI skill quick install. A companion process provisions the platform eName and keeps its Marketplace PlatformProfile synchronized from the default branch.

See docs/gitw3/platform-onboarding.md for the manifest contract, service deployment, system webhook, credentials, status integration, and failure behavior.

Licence

Forgejo is GPL-3.0-or-later, and so is GitW3. See LICENSE.

The Forgejo branding is not covered by that licence and is not ours to reuse: the logo is CC BY-SA 4.0 by Caesar Schinas, and the Jo mascot is CC BY 4.0 by David Revoy. The attribution exemption on the logo is granted to the Forgejo project only. GitW3 branding assets must therefore be original work, not derivatives of Forgejo's.

Upstream

About

GitW3 — MetaState git forge, based on Forgejo (GPLv3)

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages