Conversation
|
Updated in c0cbea0 and 1de45f3. The tag matcher now reuses the existing I also added the triggering tag name to application and Compose deployment history. This helps identify which release triggered each service in a monorepo. The existing commit message and full commit hash remain unchanged; the tag is shown only once while running and is retained after completion. No separate tag SHA or shortened commit is displayed. Build/checkout behavior is unchanged. Validation: 90 focused tests passed, and Optional tag patterns Tag names in deployment history Ready for another review. Thank you! |
| await updateDeployment(deployment.deploymentId, { | ||
| title: commitInfo.message, | ||
| description: `Commit: ${commitInfo.hash}`, | ||
| description: getDeploymentCommitDescription( |
There was a problem hiding this comment.
This changes the deployment description for every deployment, not just tag-triggered ones. Before, the finally block always wrote Commit: <hash>. Now any descriptionLog that isn't Hash: <same hash> is kept in front of it. For example:
- manual/API deploys with
input.description→"<desc>\nCommit: …" - project transfers (
transfer.ts) →"Transferred to X\nCommit: …" - compose
[refreshToken]webhooks with an empty or"NEW COMMIT"hash (GitLab/Bitbucket/Gitea fallback) →"Hash: NEW COMMIT\nCommit: …"
That's outside the scope of this PR. Could we limit it to the tag case and drop the helper?
For example:
description: descriptionLog.startsWith("Tag: ")
? `${descriptionLog}\nCommit: ${commitInfo.hash}`
: `Commit: ${commitInfo.hash}`,Then deployment-description.ts and its test can be removed, and every other deployment behaves exactly as it does today
| await updateDeployment(deployment.deploymentId, { | ||
| title: commitInfo.message, | ||
| description: `Commit: ${commitInfo.hash}`, | ||
| description: getDeploymentCommitDescription( |
There was a problem hiding this comment.
Same as in application.ts: please apply the same tag-only condition here
| const isExpanded = expandedDescriptions.has( | ||
| deployment.deploymentId, | ||
| ); | ||
| const descriptionText = (deployment.description ?? "") |
There was a problem hiding this comment.
Two things here:
text.startsWith("Tag SHA:")(L292) is dead code. Nothing writes aTag SHA:line anymore, so it looks left over. Check this- Hiding the
Tag: Xline when the title isTag created: Xonly prevents a duplicate for the minute or so the deployment is running. It also ties the UI to the exact strings the webhook produces.
I'd remove the whole split/filter/join block and render deployment.description directly. Keeping whitespace-pre-wrap on the span (L357 Check couple lines below) is enough for the multi-line description.
| /** Match the entire tag, treating only * as a wildcard (zero or more characters). */ | ||
| export function matchesTagPattern(tag: string, pattern: string): boolean { | ||
| // Keep non-star glob syntax literal to preserve the existing tag filter contract. | ||
| const glob = pattern.replace(/[\\?[\]{}()!+@|^$"]/g, "\\$&"); |
There was a problem hiding this comment.
Thanks for switching to micromatch! But escaping every glob character except * cancels most of the benefit: we end up with an escape regex, three options and a large test table that mostly tests the escaping. shouldDeploy (packages/server/src/utils/watch-paths/should-deploy.ts) uses plain micromatch globs for watch paths, and tag patterns should work the same way:
export const matchesTriggerTags = (tag: string, patterns?: string[] | null) =>
!patterns?.length || micromatch.isMatch(tag, patterns, { bash: true });This gives the same result for every documented case (go-*, *-prod, ab*ab, literal v1.2, case-sensitive, full match). The only difference is that ?, {a,b} and ! also work as globs, which is what users would expect. matchesTagPattern can be removed, and the test table can be reduced to the behavior we actually document.


What is this PR about?
Adds an optional Tag patterns field to the GitHub On Tag trigger for applications and Docker Compose services. Each service can deploy only when a pushed tag matches one of its configured names or patterns. Leaving the field empty preserves the existing behavior: every tag triggers deployment.
Why this is needed
A monorepo can contain several independently deployed services. Today, a new tag triggers every service configured for On Tag in that repository, even when the release concerns only one service. This creates unnecessary builds and deployments.
Exact names alone are not sufficient for repeated releases because Git tag names must be unique. Patterns such as
go-*allow successive releases (go-1,go-2,go-v1.2.3) without changing the Dokploy settings or reusing an existing tag. A shared pattern lets users release all services together when needed.Example
For a repository containing three services:
all-*, go-*all-*, node-one-*all-*, node-two-*go-1orgo-2: deploy only the Go API.node-one-1: deploy only Node service one.all-1: deploy all three services.The comma separates filters in Dokploy; the Git tag itself is a single name, such as
go-2. The wordallhas no special meaning: it works because the same pattern is configured on each service.Behavior and implementation
micromatchdependency with{ bash: true }, without custom escaping. Matching is case-sensitive and covers the entire tag name. The documentedgo-*,*-prod, and exact-name examples remain supported.triggerTagsarrays on applications and Compose services, with an additive database migration and generated Drizzle snapshot.Commit: <hash>behavior. No separate tag SHA or shortened commit is added.Validation
pnpm -r run typecheckpassed across all workspace projects.go-1webhook payload through the local HTTP endpoint: exactly one service was selected and its Docker deployment completed successfully.all-*routing is covered by webhook tests. External webhook delivery was blocked by a timeout in the development proxy/Tailscale connection, so this is not claimed as a successful end-to-end public-webhook test.Checklist
canarybranch.CONTRIBUTING.md.Screenshots
The GitHub On Tag settings now include optional patterns and a versioned-tag example.
The deployment history retains the triggering tag (
all-6orgo-7) alongside the existing commit message and full commit hash.The PR appears safe to merge, with no concrete correctness, security, migration, or persistence failures identified.
Summary
This PR adds optional, service-specific GitHub tag filters for applications and Compose services while preserving deploy-on-every-tag behavior when no filters are configured.
*wildcard matching.Reviews (1) · Last reviewed commit: "feat(github): filter tag-triggered deplo..."