go-gitea/gitea

Tag creation/deletion incorrectly triggers Push webhook (should only emit Create/Delete event)

Closed this issue · 16 comments

Description

Description

In Gitea 1.22.2, creating or deleting a tag emits a "push" webhook with ref set to refs/tags/....
This behavior triggers CI jobs subscribed to branch push events, even though semantically it's a tag operation.

Expected Behavior

Tag creation/deletion should trigger only a create or delete event—not a push event—so that pipelines can be scoped properly.

Actual Behavior

Gitea currently sends a push webhook for both regular branch pushes and tag events, causing unintended execution in pipelines expecting only branch triggers.

Steps to Reproduce

  1. Configure a pipeline job with webhook:
    • Trigger On: Push Event
    • Branch filter: refs/heads/main
  2. Create (or delete) a tag in Gitea.
  3. Observe that the pipeline is triggered anyway (because ref contains refs/tags/..., but the event type is still push).

Proposal

  • Add differentiation in webhook logic: a tag operation should optionally trigger only the create or delete webhook.
  • Or at minimum, support an optional configuration to exclude push events whose ref starts with refs/tags/.

This change would prevent branch-only pipelines from being inadvertently triggered by tag-related actions.

Gitea Version

1.22.2

Can you reproduce the bug on the Gitea demo site?

Yes

Log Gist

No response

Screenshots

No response

Git Version

2.49.0

Operating System

Windows

How are you running Gitea?

Windows Service

Database

None

It looks like in Gitea’s webhook code -
https://github.com/go-gitea/gitea/blob/main/models/webhook/webhook.go

the function func (w *Webhook) HasEvent(evt webhook_module.HookEventType) checks for events like Push. From what I understand, each action (create, release, etc.)
triggers its corresponding event, and in some cases, tag operations internally trigger a push event.

Id like to work on this, Any guide on how to achieve this or should i figure it out ?

lunny commented

It looks like in Gitea’s webhook code - https://github.com/go-gitea/gitea/blob/main/models/webhook/webhook.go

the function func (w *Webhook) HasEvent(evt webhook_module.HookEventType) checks for events like Push. From what I understand, each action (create, release, etc.) triggers its corresponding event, and in some cases, tag operations internally trigger a push event.

Is this still a problem for 1.24.6?

We are currently using version 1.22.2,
where we have observed this behavior. We haven’t tested version 1.24.6 yet.

The issue wasn't marked anywhere as done so im just looking into it

Id like to work on this, Any guide on how to achieve this or should i figure it out ?

Feel free to explore and figure it out. If I come across anything useful, I’ll share it here.

Thanks ill look into it and propose a fix

Hi further testing this seems to be the issue with the latest version as well, Creating / Deleting tags also causes the push event to be triggered

The easiest way to fix this is to provide a config variable to prevent push events to tags in the config file and filter it in the PrepareWebhooks() function and skip if the flag is enabled and the events has refs/tags/** how does this sound?

lunny commented

It seems the main problem is the branch filter wrongly matched refs/tags/xxx as refs/heads/main?

It seems the main problem is the branch filter wrongly matched refs/tags/xxx as refs/heads/main?

so i should add another check to see for push payload if the branch matches the tag prefix right? inside the getPayload case PushPayload

This seems to do the job fine

lunny commented

The branch filter should always check the ref name directly, rather than first determining whether it is a branch.

Should i create a PR to V.1.25?

Thanks for fixing this. Will these changes be available in version 1.22.2 or in a later update of 1.22.2 ?

Thanks for fixing this. Will these changes be available in version 1.22.2 or in a later update of 1.22.2 ?

It is in 1.26 (the current main branch) and will be backported to 1.25 (so you will see it in 1.25.0)

1.22 is outdated and not maintained.