惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
L
LangChain Blog
Engineering at Meta
Engineering at Meta
F
Fortinet All Blogs
N
Netflix TechBlog - Medium
M
MIT News - Artificial intelligence
IT之家
IT之家
The Register - Security
The Register - Security
月光博客
月光博客
Hugging Face - Blog
Hugging Face - Blog
The GitHub Blog
The GitHub Blog
博客园 - 聂微东
云风的 BLOG
云风的 BLOG
Microsoft Security Blog
Microsoft Security Blog
腾讯CDC
W
WeLiveSecurity
博客园_首页
A
About on SuperTechFans
G
Google Developers Blog
博客园 - 叶小钗
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
量子位
Google DeepMind News
Google DeepMind News
博客园 - 【当耐特】
aimingoo的专栏
aimingoo的专栏
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 三生石上(FineUI控件)
N
News | PayPal Newsroom
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
AI
AI
TaoSecurity Blog
TaoSecurity Blog
P
Proofpoint News Feed
Attack and Defense Labs
Attack and Defense Labs
S
Secure Thoughts
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 司徒正美
www.infosecurity-magazine.com
www.infosecurity-magazine.com
J
Java Code Geeks
Hacker News - Newest:
Hacker News - Newest: "LLM"
爱范儿
爱范儿
S
SegmentFault 最新的问题
Martin Fowler
Martin Fowler
Vercel News
Vercel News
Schneier on Security
Schneier on Security
Know Your Adversary
Know Your Adversary
H
Heimdal Security Blog
N
News and Events Feed by Topic

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
CI/CD, YAML, Azure DevOps and Merge Conflicts: Everything I Learned Deploying to Azure
Manohari Jayachandran · 2026-06-18 · via DEV Community

My first production deployment at Blue Yonder was entirely manual. Copy files to the server. Update the config by hand. Restart the service. Call the team to verify it was live. The whole process took 45 minutes, produced a slightly different result every time depending on who ran it, and only two people on the team knew all the steps.

Then we moved to automated pipelines. The same deployment became: push code to Git, wait 4 minutes, done. Same result every single time. Anyone on the team could trigger it. Full audit log of every deployment. Rollback in one command.

CI/CD is not a nice-to-have for serious software delivery. It is the foundation. This post covers everything — YAML syntax, GitHub Actions, Azure DevOps, deployment strategies, merge conflicts, and the security practices that keep pipelines safe.

CI vs CD — The Actual Difference

Most people use CI/CD as one term without knowing where one ends and the other begins.

Continuous Integration is about merging code frequently and automatically verifying it. Every time a developer pushes code, the CI system builds it and runs tests. The goal is to catch problems immediately — within minutes of the bad code being merged, not days later when someone manually tests the feature.

Continuous Deployment takes the verified build from CI and automatically deploys it to one or more environments. Continuous Delivery deploys automatically to staging but requires a human to approve the production deployment. Continuous Deployment goes all the way to production automatically with no human approval.

A complete pipeline looks like this:

Code pushed -> Build -> Unit tests -> Integration tests
-> Deploy to dev -> Deploy to staging -> Manual approval
-> Deploy to production.

TechStack Blog uses a simplified version of this — every push to main builds the C# API, publishes it, and deploys to Azure App Service automatically. No staging environment for a solo blog project, but the same principles apply.

YAML — The Language of Pipelines

YAML (Yet Another Markup Language) is the format used by GitHub Actions, Azure DevOps, and almost every modern CI/CD tool. It uses indentation to show structure and is readable as plain text.

The critical rule: indentation must be consistent and use spaces, never tabs. One wrong indent and the pipeline fails with a cryptic error.

The basic structure of any pipeline has three parts.
The trigger defines when the pipeline runs — on push, on pull request, on a schedule, or manually.
The jobs define what machines do the work and in what order.
The stepsdefine the individual commands each machine runs.

  • Lists use a dash at the start of each item.
  • Objects use key-value pairs with a colon.
  • Nested structure uses consistent indentation.
  • Secrets and variables are referenced with double curly braces.

Understanding these four rules lets you read any YAML pipeline file regardless of which CI/CD platform wrote it.

GitHub Actions

GitHub Actions is CI/CD built directly into GitHub. Every workflow is a YAML file stored in the .github/workflows/ folder of your repository. When the trigger condition is met — a push, a PR, a schedule — GitHub spins up a fresh virtual machine, runs your steps, and tears the machine down when done.

The TechStack Blog API deployment workflow does eight things in sequence.

  1. It checks out the repository code.
  2. It installs the .NET 8 SDK.
  3. It restores NuGet packages.
  4. It builds the C# project in Release mode.
  5. It runs tests.
  6. It publishes the output to a folder.
  7. It zips that folder.
  8. It logs into Azure using service principal credentials stored as GitHub Secrets and deploys the zip to Azure App Service.

The entire process takes 3-4 minutes. Every push to main triggers it automatically.

The most important concept in GitHub Actions is job dependencies. The deploy job has "needs: build" which means it only runs if the build job succeeds. If the build fails the deployment never happens. This prevents
broken code from reaching Azure.

Secrets in GitHub Actions are stored encrypted and never appear in logs. They are referenced with the ${{ secrets.SECRET_NAME }} syntax. The Azure service principal credentials — client ID, tenant ID, and subscription ID — are stored as secrets so they never appear in the YAML file that is publicly visible in the repository.

Azure DevOps Pipelines

Azure DevOps is Microsoft's enterprise CI/CD platform. It has more features than GitHub Actions and is the standard in large organizations. At Blue Yonder, Azure DevOps managed our integration platform deployments
across multiple environments with formal approval workflows.

The key difference from GitHub Actions is the concept of stages with environments. You define a Production environment in Azure DevOps and configure it to require approval from specific people before any deployment can proceed. When the pipeline reaches the production stage, it pauses and sends an email to the approvers. Only after someone clicks Approve does the deployment continue.

This is the approval gate pattern — critical for any system where a bad deployment has real consequences. GitHub Actions has similar functionality through Environment protection rules, but Azure DevOps makes it more prominent and easier to configure for teams.

Azure DevOps also has variable groups — shared sets of variables that multiple pipelines can reference. Instead of duplicating the same connection string in ten different pipeline files, you define it once in
a variable group and all pipelines inherit it. When the value changes, you update it in one place.

Manual vs Automated Deployment

Automated deployment is the goal but manual deployment has its place. Know when to use each.

Automate everything that runs repeatedly and must produce identical results every time. Application code, configuration changes, dependency updates — these all belong in automated pipelines.

Keep manual control over things that require judgment. Database schema migrations that could lose data. First-time infrastructure provisioning with Terraform or Bicep. Emergency hotfixes that are faster to deploy manually than waiting for a pipeline. Deployments that require physically touching hardware.

The hybrid approach that works in practice: code deployments are fully automated, database migrations are automated with a manual approval step, infrastructure changes are manual with documentation, and production releases require a pipeline approval gate even though the deployment itself is automated.

Deployment Strategies

Blue-Green deployment runs two identical environments. Traffic goes to the blue environment (live). You deploy to the green environment (idle) and test it. When ready, you switch all traffic to green in seconds. Blue becomes the instant rollback target. Azure App Service deployment slots implement this pattern directly — swap slots to go live, swap back to roll back.

Canary deployment sends a small percentage of traffic to the new version first. Start at 5%, monitor for errors, increase to 25%, then 50%, then 100%. If errors appear at any stage, roll back the canary percentage.
Real users test the new version but only a small fraction of them are exposed to any problems.

Rolling deployment updates one server at a time while the others keep serving traffic. No downtime but slower to roll back — you have to wait for the rolling update to complete in reverse.

For a single-server deployment like TechStack Blog, the simplest strategy is stop, replace, start. Acceptable for a blog. Not acceptable for a system that needs zero downtime.

Merge Conflicts

A merge conflict happens when two developers change the same line of the same file and Git cannot automatically decide which change to keep. This is the moment most new developers dread. Once you understand it, conflicts
are completely manageable.

The scenario: main branch has a function returning "Hello". Developer A changes it to "Hello World" and merges first. Developer B changes the same line to "Hi there" and tries to merge. Git sees both changed the same line and does not know which version is correct. Git marks the file and asks you to decide.

What Git puts in the file:


<<<<<<< HEAD
your version of the code here
=======
their version of the code here
>>>>>>> their-branch-name

Everything between the less-than signs and the equals signs is your version. Everything between the equals signs and the greater-than signs is their version.

To resolve: delete both markers, keep whichever code is correct (or combine both), save the file, run git add on the resolved file, then git commit to complete the merge.

VS Code shows conflict markers with clickable buttons — Accept Current Change, Accept Incoming Change, Accept Both Changes. Click the appropriate button, VS Code removes the markers automatically, save and commit.

Preventing Merge Conflicts

Pull before you push every single time. This one habit eliminates the majority of conflicts by keeping your local branch close to the current state of main.

Commit small and commit often. Large commits that change many files across many features create maximum overlap with other developers' work. Small focused commits targeting specific files create minimum overlap.

Keep feature branches short-lived. Branches that live for weeks diverge significantly from main and produce massive conflicts when merged. Aim for branches that live 1-3 days and get merged back through a pull request.

Communicate about shared files. When you know you are making significant changes to a file that others also work in, mention it to the team. Simple coordination prevents most serious conflicts.

Branch Strategies

GitFlow uses long-lived branches for different purposes.

  • A main branch contains only production-ready code.
  • A develop branch is the integration point where features are merged before going to production.
  • Feature branches come off develop and merge back into develop.
  • Release branches prepare for a production deployment.
  • Hotfix branches patch production issues directly.

This maps cleanly to CI/CD: develop branch triggers deployment to the dev environment, release branch triggers staging deployment, main branch triggers production deployment with approval.

Trunk-Based Development keeps almost everything in one branch — main (or trunk). Feature branches exist but are short-lived, typically 1-3 days maximum. Feature flags control what users see rather than long-lived branches. Every merge to main can safely deploy to production. This is the approach modern engineering teams use when they want to deploy multiple times per day.

TechStack Blog uses simplified trunk-based: one main branch, everything deploys automatically. Works perfectly for a solo developer project.

Pipeline Security

Never put actual values for secrets in YAML files. A YAML file in a public GitHub repository is visible to everyone. Any secret in that file is compromised the moment you commit it. Use ${{ secrets.NAME }} and
store the actual value in GitHub Secrets or Azure DevOps variable groups.

Pin your action versions. Using actions/checkout@main means your pipeline uses whatever version is current at the time it runs. That version can change without warning and silently break your pipeline or introduce malicious code. Use actions/checkout@v4 for a specific
stable version.

Give your service principal the minimum permissions it needs to deploy. If the pipeline only needs to deploy to one App Service, its Azure role should only allow that — not manage billing, not delete resources, not
create new services.

Use environment protection rules for production. In GitHub Settings, create a Production environment and require one or more specific people to approve before any deployment can proceed.

Key Lessons From Production

  • Set up CI/CD before writing business logic. Retrofitting a pipeline into an existing project is significantly harder than building it alongside the first commit. The TechStack Blog pipeline was configured on day one.

  • Keep pipelines fast. If building and deploying takes more than 10 minutes, developers stop waiting for results and start pushing anyway. Cache dependencies, run tests in parallel, and skip unnecessary steps.

  • Test your rollback before you need it. A rollback plan you have never practiced is not a plan. Every team should do a rollback drill in staging at least once per quarter.

  • Never let a broken pipeline stay broken. A broken pipeline is ignored. An ignored pipeline means changes go unverified. Fix pipeline failures immediately — treat them with the same urgency as a production outage.

Summary

CI/CD automates the path from code to running software. YAML defines the pipeline steps in a readable, version- controlled format. GitHub Actions brings CI/CD directly into your GitHub workflow with zero additional tooling. Azure DevOps adds enterprise approval gates and environment management for organizations that need them. Merge conflicts are a normal part of collaborative development — understand the markers, resolve deliberately, prevent through good habits. Together these practices make deployment reliable, repeatable, and safe.

The TechStack Blog goes from git push to live in 4 minutes automatically, every time, with no manual steps. That is what CI/CD is for.


Originally published at TechStack Blog:
https://www.techstackblog.com

Follow for weekly posts on Azure, C#, DevOps, and cloud engineering.