Skip to content

fix: add write:repository scope to Gitea OAuth for webhook creation#4413

Open
lamualfa wants to merge 3 commits into
Dokploy:canaryfrom
lamualfa:fix/gitea-webhook-oauth-scopes
Open

fix: add write:repository scope to Gitea OAuth for webhook creation#4413
lamualfa wants to merge 3 commits into
Dokploy:canaryfrom
lamualfa:fix/gitea-webhook-oauth-scopes

Conversation

@lamualfa
Copy link
Copy Markdown

@lamualfa lamualfa commented May 15, 2026

Summary

  • Add write:repository to Gitea OAuth scopes in all three configuration locations
  • Add createGiteaWebhook utility to automatically create push webhooks in Gitea repos
  • Auto-create webhooks when saving Gitea-linked applications or compose projects

Problem

The Gitea OAuth scopes across the codebase only requested read permissions. On GitHub, the repo scope grants full read/write access to repositories. On Gitea, repo maps to read:repository only. Creating webhooks via POST /api/v1/repos/{owner}/{repo}/hooks requires the write:repository scope.

Additionally, Dokploy never automatically creates webhooks in Gitea repositories (unlike the GitHub integration which uses GitHub Apps). Users had to manually configure webhooks in the Gitea UI pointing to Dokploy's deploy endpoint.

Changes

Scope fix (prerequisite)

File Change
apps/dokploy/pages/api/providers/gitea/authorize.ts Added write:repository to OAuth authorize scope
apps/dokploy/utils/gitea-utils.ts Added write:repository to client-side OAuth scope
packages/server/src/db/schema/gitea.ts Added write:repository to default scopes

Auto webhook creation (new feature)

File Change
packages/server/src/utils/providers/gitea.ts Added createGiteaWebhook() utility function
apps/dokploy/server/api/routers/application.ts Call webhook creation in saveGiteaProvider handler
apps/dokploy/server/api/routers/compose.ts Call webhook creation in update handler when sourceType is "gitea"

Implementation details

The createGiteaWebhook function:

  • Refreshes the Gitea OAuth token before making API calls
  • Checks for existing webhooks to avoid duplicates (matches by deploy path)
  • Uses giteaInternalUrl when available for Docker co-hosted setups
  • Constructs the Dokploy webhook URL from request headers (x-forwarded-proto + host)
  • Uses the correct endpoint path based on resource type:
    • Applications: /api/deploy/{refreshToken}
    • Compose: /api/deploy/compose/{refreshToken}
  • Errors are caught and logged to avoid blocking the save operation

Test plan

  • Connect a Gitea provider with the updated scopes
  • Create a compose linked to a Gitea repo, enable auto-deploy
  • Verify a webhook is created in the Gitea repository (Settings > Webhooks)
  • Verify webhook URL uses /api/deploy/compose/{token} path
  • Push a commit and verify deployment triggers automatically
  • Create an application linked to a Gitea repo
  • Verify webhook URL uses /api/deploy/{token} path
  • Save again and verify no duplicate webhooks are created
  • Disconnect the Gitea provider and verify behavior
  • Verify existing Gitea providers still work (existing tokens may need re-authentication to get the new write:repository scope)

Closes #4412

The Gitea OAuth scopes across the codebase only requested read permissions.
On Gitea, the `repo` scope maps to `read:repository` only (unlike GitHub
where `repo` grants full read/write). Creating webhooks via the Gitea API
requires `write:repository`, so Dokploy was silently unable to create
webhooks in Gitea repos, causing auto-deploy to never trigger.

Closes Dokploy#4412
@lamualfa lamualfa requested a review from Siumauricio as a code owner May 15, 2026 22:12
@dosubot dosubot Bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label May 15, 2026
Add createGiteaWebhook utility that creates push webhooks in Gitea
repositories when a Gitea-linked application or compose is saved.
Checks for existing hooks to avoid duplicates. Uses correct endpoint
path based on resource type (application vs compose).

Called from:
- saveGiteaProvider (application router)
- update handler (compose router, when sourceType is "gitea")

Errors are caught and logged to avoid blocking the save operation.
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels May 15, 2026
apiUpdateCompose is a partial schema, so giteaOwner and giteaRepository
may be undefined when sourceType is "gitea". Add explicit truthy checks
instead of falling back to empty strings.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gitea webhooks never created — OAuth scopes missing write:repository

1 participant