<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Piyush Gaikwad</title>
    <description>The latest articles on Forem by Piyush Gaikwad (@piyushgaikwaad).</description>
    <link>https://forem.com/piyushgaikwaad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3672337%2F26725c92-4853-4713-8a12-7fe01ec2ee73.jpg</url>
      <title>Forem: Piyush Gaikwad</title>
      <link>https://forem.com/piyushgaikwaad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/piyushgaikwaad"/>
    <language>en</language>
    <item>
      <title>How to Enforce Policies Without Blocking Hotfixes</title>
      <dc:creator>Piyush Gaikwad</dc:creator>
      <pubDate>Fri, 26 Dec 2025 06:05:05 +0000</pubDate>
      <link>https://forem.com/piyushgaikwaad/how-to-enforce-policies-without-blocking-hotfixes-7dh</link>
      <guid>https://forem.com/piyushgaikwaad/how-to-enforce-policies-without-blocking-hotfixes-7dh</guid>
      <description>&lt;p&gt;Hotfixes are different by nature.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They are urgent, because production is already impacted.&lt;/li&gt;
&lt;li&gt;They are small, because the goal is to stop the bleeding, not redesign the system.&lt;/li&gt;
&lt;li&gt;They are high-risk, because they touch live systems under pressure.&lt;/li&gt;
&lt;li&gt;And they are high-impact, because even a one-line change can affect thousands or millions of users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yet many teams still apply exactly the same rules to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a large feature PR with weeks of context, and&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;one-line production fix at 2 AM&lt;/strong&gt; during an incident.
This mismatch is where friction — and eventually policy violations — begin.

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The “Tag to Skip Checks” Anti-Pattern
&lt;/h2&gt;

&lt;p&gt;Most organizations already feel this pain, which is why a common workaround exists.&lt;br&gt;
Teams introduce:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;labels like &lt;strong&gt;skip-ci&lt;/strong&gt;, &lt;strong&gt;emergency&lt;/strong&gt;, &lt;strong&gt;hotfix&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;manual tags that disable required checks&lt;/li&gt;
&lt;li&gt;undocumented conventions known only to senior engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;On paper, this looks like speed. In practice, it’s silent policy erosion.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once skipping checks becomes normal:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;accountability drops&lt;/li&gt;
&lt;li&gt;audits become painful&lt;/li&gt;
&lt;li&gt;security teams lose trust in CI signals&lt;/li&gt;
&lt;li&gt;“emergency” becomes a habit, not an exception&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem is not the desire for speed — it’s that tags remove guardrails instead of reshaping them.&lt;/p&gt;



&lt;h2&gt;
  
  
  2 Pipeline Checks
&lt;/h2&gt;

&lt;p&gt;Most modern engineering systems today rely on a Git-based workflow, where even hotfixes are required to flow through Pull Requests (PRs). These PRs are protected by required checks that must succeed before a change can be merged. To avoid blocking urgent fixes, many organizations split validation into two deliberate stages. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pre-merge checks:&lt;/strong&gt; The first stage consists of pre-merge checks, which are intentionally fast and lightweight, focused on validating that the change does not immediately break tests or violate basic policies. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;pre-checkin :&lt;/strong&gt; Once these checks pass, developers are allowed to proceed with pre-checkin. A successful pre-checkin automatically merges the PR, removing manual delays while still ensuring that every hotfix follows a controlled, auditable path.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In most of the companies, to merge a change it is requried to successfully pass &lt;strong&gt;Pre-merge checks&lt;/strong&gt; and &lt;strong&gt;pre-checkin check&lt;/strong&gt;;  For &lt;em&gt;Hotfix&lt;/em&gt; changes to go in faster, Pre-merge checks can be made reliant by using &lt;strong&gt;Ruleset&lt;/strong&gt; or &lt;strong&gt;branch protection rules&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What a Good Hotfix Ruleset Looks Like:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pull request still required (no direct pushes)&lt;/li&gt;
&lt;li&gt;fewer, faster required checks (unit, smoke, secret scanning)&lt;/li&gt;
&lt;li&gt;approvals required, but limited to on-call / release owners&lt;/li&gt;
&lt;li&gt;force pushes still blocked&lt;/li&gt;
&lt;li&gt;bypass allowed only to a very small group, and always logged&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>productivity</category>
      <category>devops</category>
      <category>git</category>
    </item>
    <item>
      <title>Branch Protection Rules vs Rulesets: The Right Way to Protect Your Git Repository</title>
      <dc:creator>Piyush Gaikwad</dc:creator>
      <pubDate>Sun, 21 Dec 2025 07:55:13 +0000</pubDate>
      <link>https://forem.com/piyushgaikwaad/branch-protection-rules-vs-rulesets-the-right-way-to-protect-your-git-repos-305m</link>
      <guid>https://forem.com/piyushgaikwaad/branch-protection-rules-vs-rulesets-the-right-way-to-protect-your-git-repos-305m</guid>
      <description>&lt;p&gt;Do you need a lot of manual clicking every time a new branch is created or a repository rule needs to be enforced 🧐? That's usually a sign that traditional Branch Protection Rules are doing more work than they were designed for. &lt;/p&gt;

&lt;p&gt;If you’ve worked on a repository with more than a handful of branches, you’ve probably felt it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;duplicated branch protection rules&lt;/li&gt;
&lt;li&gt;subtle inconsistencies between main, release/&lt;em&gt;, and hotfix/&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;accidental gaps in enforcement&lt;/li&gt;
&lt;li&gt;configuration drift no one notices until production breaks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Branch Protection Rules:&lt;br&gt;
✅ You can protect main or release/*&lt;br&gt;
✅ You can enforce PR-based workflows&lt;br&gt;
❌ You cannot prevent unstructured branch names from being created&lt;br&gt;
❌ You cannot enforce naming conventions at branch creation time&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Branch Protection Rules operate after a branch exists.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As teams scale, enforcing consistent policies across branches, tags, and repositories becomes increasingly &lt;strong&gt;manual&lt;/strong&gt; and error-prone. This is where Rulesets come in—shifting governance from per-branch configuration to centralized, reusable policies that apply &lt;strong&gt;automatically&lt;/strong&gt; as your repository evolves.&lt;/p&gt;
&lt;h2&gt;
  
  
  Rulesets were designed to solve these below gaps:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;b&gt;Centralized and reusable Rules:&lt;/b&gt;&lt;/li&gt; 
&lt;p&gt; With branch protection, rules live at the repository level and are often duplicated across projects. Rulesets enable centralized governance, allowing organizations to define consistent policies that can be reused across repositories. This is especially valuable for platform teams managing standards at scale.
&lt;/p&gt;


&lt;li&gt;&lt;b&gt;Coverage beyond branches:&lt;/b&gt;&lt;/li&gt;

&lt;p&gt; Branch protection rules apply only to branches. Rulesets extend embed governance to Tags, Multiple branch patterns, and Repository-wide events. &lt;br&gt;This makes rulesets suitable for release processes, versioned tagging strategies, and broader repository controls that branch protection cannot address.&lt;/p&gt;


&lt;li&gt;&lt;b&gt;No need for hooks enforcement for branch name rules&lt;/b&gt;&lt;/li&gt;

&lt;p&gt;With rulesets, branch naming policies can be enforced natively at the repository level, eliminating the need for client-side Git hooks or custom validation scripts.

&lt;/p&gt;


&lt;li&gt;&lt;b&gt;Reduced operational overhead&lt;/b&gt;&lt;/li&gt;

&lt;p&gt;By eliminating repetitive configuration and manual updates, rulesets reduce the operational burden on maintainers. Policies continue to apply automatically as new branches or tags are created, ensuring protection is not accidentally bypassed.
&lt;/p&gt;


&lt;/ol&gt;




&lt;blockquote&gt;
&lt;p&gt;Now, Let's explore on how the ruleset can go beyond branch protection rules and help in enforcing the creation of unstructured branch names 🤩&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;Let’s say you want to implement an orchestrated branching workflow, where different types of branches follow different rules &lt;strong&gt;before they are created, not after&lt;/strong&gt;. &lt;br&gt;
In many organizations, feature branches, hotfix branches, and release branches each serve a distinct purpose and therefore require different validation, checks, or governance policies. Branch Protection Rules cannot model this kind of workflow because they apply only once a branch already exists and are limited to protecting a fixed set of branches.&lt;/p&gt;

&lt;p&gt;With rulesets, you can define multiple policies, each targeting a specific branch pattern, and enforce them at creation time. &lt;/p&gt;

&lt;p&gt;For example, you might require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;feature/&lt;/strong&gt;* : branches to pass basic CI checks,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;hotspot/&lt;/strong&gt;* : branches to require additional approvals or stricter checks,&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;release/&lt;/strong&gt;*: branches to enforce mandatory reviews and block force pushes entirely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each ruleset is evaluated automatically as the branch is created, ensuring that the correct governance model is applied from the very beginning. This allows teams to encode branching strategy directly into the platform, rather than relying on post-creation enforcement or manual discipline.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrivwdetdc39sfsng1z2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrivwdetdc39sfsng1z2.png" alt="RULESET VS BRANCH protection rules" width="800" height="706"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;blockquote&gt;
&lt;p&gt;Now, Let's explore on how there is no need to maintain a separate server-side hook to prevent unstructured branch names such as &lt;b&gt;hot-spot/fix-check&lt;/b&gt; when the requirement is simply to enforce a consistent prefix like &lt;b&gt;hotspot/*&lt;/b&gt; 😍.&lt;/p&gt;


&lt;/blockquote&gt;

&lt;p&gt;As teams grow, branch naming conventions tend to drift. What starts as a simple guideline—“please prefix branches correctly”—quickly turns into a mix of inconsistent names created through different tools and workflows.&lt;br&gt;
Common problems include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers creating branches like hot-spot/fix-check instead of the intended hotspot/fix-check&lt;/li&gt;
&lt;li&gt;Missing team or ticket identifiers in branch names&lt;/li&gt;
&lt;li&gt;Inconsistent naming across CLI, GitHub UI, and automation&lt;/li&gt;
&lt;li&gt;Relying on documentation or tribal knowledge to enforce standards
To address this, teams often introduce custom pre-receive hooks or manual review processes, which add operational overhead and require ongoing maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sample pre-receive hooks to prevent pushing forbidden branches or adhere to branch namespace looks like:&lt;/p&gt;

&lt;pre&gt;
#!/bin/bash

FORBIDDEN_BRANCH="refs/heads/forbidden-branch"

while read oldrev newrev refname
do
   if [[ "$refname" =~ ^refs/heads/(master|release/.*)$ ]]; then
     echo "Push rejected: direct pushes to 'master/' or 'release/*' branches are not allowed."
     echo "Please use a pull request instead."
     exit 1
  fi

  if [[ "$refname" == "$FORBIDDEN_BRANCH" ]]; then
    echo "Push rejected: pushing to 'forbidden-branch' is not allowed."
    echo " Please create a branch with an approved naming convention."
    echo "Branch name starting with &amp;lt;user-id&amp;gt;/&amp;lt;org&amp;gt;/*
 are only allowed."
    exit 1
  fi
done

exit 0
&lt;/pre&gt;

&lt;p&gt;Instead create a simple ruleset to avoid push from unknown branches by creating a new ruleset:&lt;br&gt;
&lt;/p&gt;
&lt;ol&gt;

&lt;li&gt;&lt;b&gt;Go to settings and select rulesets&lt;/b&gt;&lt;/li&gt;

&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2nxg9du59iw7975l8ort.png" alt="Select the ruleset" width="516" height="316"&gt;




&lt;li&gt;&lt;b&gt;Now add necessary details about Ruleset Name, Enforcements, Bypass list and Target branches.&lt;/b&gt;&lt;/li&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt4u28wyupiywic9hpia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdt4u28wyupiywic9hpia.png" alt="New branch ruleset" width="800" height="681"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;li&gt;&lt;b&gt; Now scroll down to bottom and fill the details to optimize the workflow&lt;/b&gt;&lt;/li&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdm64o3gra35o9i2uuwh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdm64o3gra35o9i2uuwh.png" alt="Add the branch name spacing pattern " width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpylcmb0ce3xbzixijyf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpylcmb0ce3xbzixijyf8.png" alt="Finally" width="800" height="181"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and done 🥳🥳.&lt;br&gt;
This will atomically trigger whenever user tries to push new branches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion:
&lt;/h2&gt;

&lt;p&gt;Branch Protection Rules are not obsolete—they still provide essential safeguards for critical branches. But as repositories grow and governance requirements become more complex, relying solely on branch-by-branch configuration and custom hooks starts to introduce friction, duplication, and maintenance overhead. Rulesets represent a shift from reactive protection to proactive governance, allowing policies to be defined once and applied consistently as repositories evolve.&lt;/p&gt;

&lt;p&gt;The real value of rulesets is not just fewer clicks in the UI, but a clearer separation of concerns: platform-level policies enforced centrally, and developer workflows kept simple and predictable. When used correctly, rulesets eliminate the need for many custom server-side hooks, reduce configuration drift, and make repository standards easier to scale across teams and organizations. In short, branch protection rules secure branches—but rulesets secure the process. If you want to use it in your repository, read about management &lt;a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-rulesets/about-rulesets" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;


&lt;/ol&gt;

</description>
      <category>git</category>
      <category>programming</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
