No More Deploying From The Laptop: Azure CI/CD For The Aiva Backend
For a while the Aiva backend went out the way a lot of backends go out: from a laptop, by hand, by whoever was closest.
That works right up until it does not. You get the deploy where someone had a local change they forgot about. You get the one where the build machine had a different SDK. You get the classic, where it works on your machine and nowhere else, and nobody can say what actually shipped.
So: a GitHub Actions workflow, build and deploy to Azure App Service on push to main. Nothing clever. That is the point. The boring version is the one that works at 2am.
What it buys you
One definition of a build. The pipeline is the only thing that produces a deployable artefact, so the question "what is in production" has one answer and it is a commit hash.
No credentials on anyone's laptop. Publish profile lives in the repo secrets. Nobody needs the Azure portal to ship.
A deploy you can read. Every deploy has a log, a commit, and a person attached to it. When something breaks at 4pm you start from "what changed" instead of "who was deploying".
The bug we found on the way
While wiring it up I went to check what was excluded from the published output, and found the .gitignore had inline comments on the end of pattern lines. Like this:
*.sh # helper scripts
Git does not treat that as a pattern plus a comment. It treats the whole thing as the pattern, trailing spaces and hash and all. So *.sh was not being ignored. Neither were a few other things on lines written the same way.
Which meant appsettings.Development.json and a local Claude settings file had been sitting in the repo. With keys in them.
Both removed from tracking, keys rotated. A key that has been committed is not a key any more, it is a liability with an expiry date you do not control.
That one is worth knowing about generally: put comments on their own line in a .gitignore. The failure is completely silent and you only notice when you go looking for something else.
Also in this change
The Shopify subscriptions app, the HighLevel MCP server, and the client onboarding docs all landed in the same push. Less interesting, but it is where they came in, and dates matter when you are trying to remember what existed when.
The honest bit
None of this is exciting work. It is the sort of thing that gets pushed back because it does not show up in a demo. It also means the next time something needs shipping in a hurry, the shipping part is not the risk.