Skip to content

feat(ci): add hotfix cherry-pick and release workflows - #4977

Merged
Siumauricio merged 1 commit into
canaryfrom
feat/hotfix-release-flow
Aug 6, 2026
Merged

feat(ci): add hotfix cherry-pick and release workflows#4977
Siumauricio merged 1 commit into
canaryfrom
feat/hotfix-release-flow

Conversation

@Siumauricio

@Siumauricio Siumauricio commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Adds a hotfix flow so urgent bug fixes can ship as patch releases without waiting for the next big canary → main merge.

How it works

  • hotfix-cherry-pick.yml — when a PR labeled hotfix is merged into canary, the bot cherry-picks it onto main and pushes with the default GITHUB_TOKEN, which intentionally does not trigger other workflows. Fixes accumulate silently on main. A concurrency group queues concurrent cherry-picks so they don't race.
  • hotfix-release.yml — manual workflow_dispatch button: bumps the patch version in apps/dokploy/package.json (preserving the v prefix) and pushes with HOTFIX_PUSH_TOKEN (PAT), which does trigger the existing dokploy.yml build + release. One click = one release with all accumulated fixes.

Rules

  • Hotfixes must be code-only — never Drizzle migrations (out-of-order migrations get silently skipped by the migrator on stable instances). A migration in a cherry-pick will conflict on _journal.json and fail loudly.
  • Big releases are unchanged: manual bump + canary → main merge.

Requires the hotfix label and the HOTFIX_PUSH_TOKEN repo secret (already configured).

Greptile Summary

Adds two GitHub Actions workflows for accumulating hotfix commits on main and manually releasing them with a patch-version bump.

  • Cherry-picks merged, labeled PRs onto main under a shared concurrency group.
  • Uses a PAT-backed version-bump push to trigger the existing main release pipeline.
  • The cherry-pick eligibility and content checks do not fully enforce the described hotfix boundary.

Confidence Score: 2/5

The PR should not merge until hotfix promotion is restricted to canary-targeted, migration-free PRs.

The new write-capable workflow accepts merged labeled PRs from any base branch and cherry-picks complete commits without excluding migrations, allowing both the intended branch boundary and migration-ordering invariant to be bypassed.

Files Needing Attention: .github/workflows/hotfix-cherry-pick.yml; .github/workflows/hotfix-release.yml

Security Review

The cherry-pick workflow can promote a labeled PR merged into a branch other than canary because it does not validate the PR base branch. Both privileged workflows also use a mutable checkout action tag.

Reviews (1): Last reviewed commit: "feat(ci): add hotfix cherry-pick and rel..." | Re-trigger Greptile

Greptile also left 3 inline comments on this PR.

@dosubot dosubot Bot added size:XS This PR changes 0-9 lines, ignoring generated files. release labels Aug 6, 2026
@Siumauricio
Siumauricio merged commit ba24ae6 into canary Aug 6, 2026
5 checks passed
@Siumauricio
Siumauricio deleted the feat/hotfix-release-flow branch August 6, 2026 05:34

jobs:
cherry-pick:
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'hotfix')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 security Missing canary branch boundary

When a hotfix-labeled PR is merged into any branch other than canary, this condition still accepts its merge commit and the write-enabled job cherry-picks it directly onto main, bypassing the intended canary integration path. How this was verified: The event has no branch filter, and the job condition checks only merged state and the hotfix label before pushing to main.

Suggested change
if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'hotfix')
if: github.event.pull_request.merged == true && github.event.pull_request.base.ref == 'canary' && contains(github.event.pull_request.labels.*.name, 'hotfix')

Comment on lines +28 to +32
SHA="${{ github.event.pull_request.merge_commit_sha }}"
if [ "$(git rev-list --parents -n1 "$SHA" | wc -w)" -gt 2 ]; then
git cherry-pick -x -m 1 "$SHA"
else
git cherry-pick -x "$SHA"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Migration restriction is unenforced

When a labeled hotfix contains a Drizzle migration that applies cleanly, this unrestricted cherry-pick promotes it to main, allowing stable installations to skip the out-of-order migration or run with a schema inconsistent with the released application. Add an explicit changed-path check that rejects migration and journal files rather than relying on a merge conflict.

contents: write
steps:
- name: Checkout main
uses: actions/checkout@v4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 security Privileged action uses mutable tag

Both new workflows resolve actions/checkout@v4 through a mutable tag while granting credentials that can push to main; pinning checkout to a full commit SHA prevents an upstream tag move from changing privileged code without repository review. How this was verified: The cherry-pick job grants contents: write, and the release checkout receives HOTFIX_PUSH_TOKEN.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release size:XS This PR changes 0-9 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant