Darshil Explains: Building a Tag-Based CI/CD Pipeline on Google Cloud
Darshil builds a tag-based CI/CD pipeline for a doctor-facing sepsis diagnosis frontend, reusing an existing Workload Identity Federation pool and shipping a two-stage Docker container to Cloud Run only when a git tag is pushed.
Darshil walks through what had to exist before a code push could turn into a running service for Medas, the frontend of an AI-assisted sepsis diagnosis tool doctors use to review output. The video covers the GCP trust chain, the application itself, and the tag-based pipeline that ties the two together.
Setting up a place for the built image to live
The first step is creating a dedicated Artifact Registry repository for the frontend, in the same GCP project and region the backend already uses. There is no need to duplicate infrastructure that already exists elsewhere in the project; the frontend just needs its own registry entry within it.
Reusing an existing identity path instead of building a new one
Rather than standing up a second Workload Identity Federation pool for the frontend, Darshil reuses the one the backend already has. The existing GitHub provider inside that pool currently trusts only the backend's repository, so its attribute condition gets widened to also accept the frontend repo. That lets both repositories authenticate through the same door. Recognition alone is not enough, though: the shared GitHub Actions service account still has to explicitly agree to be impersonated by the new repository, with a role binding scoped to exactly that repo.
Configuring GitHub secrets and variables
On the GitHub side, a new environment named "dev" holds two secrets and seven variables. Neither secret is a long-lived credential; they are just the provider path and the service account email needed to request a token. The variables assemble the image tag and point the deployment at the correct project, region, and service.
What the app itself looks like
Before getting into the pipeline, Darshil covers what it actually ships: a Vite and React frontend for doctors reviewing AI-assisted sepsis diagnosis output. The app gates access, no token, no diagnostic view. The doctor-facing pieces live under components: diagnosis editing, sepsis panels and an output table, a dialogue thread, and a microphone button for voice input.
Deciding when a deploy should actually happen
With the trust chain and the app both ready, nothing yet tied a code change to a running service; every deploy had been a manual build on someone's machine. The design decision here is a tag-based CI/CD pipeline: pushing a tag triggers a build, push, and deploy, rather than triggering on every commit. Only a tag like dev, stage-v, a bare v, or a push to master triggers a build. Tagging is treated as the moment someone decides a given commit is promotable, not the moment it was written.
Building a lean two-stage container
The container build has two stages. A Node stage builds the Vite app, with the API URL and version baked in as build arguments, because Vite inlines these values into the bundle at build time rather than reading them at container runtime. A clean Nginx image then serves only the built dist folder; none of the Node toolchain ships in the final image. The workflow authenticates using the identity set up earlier, builds the image with the variables from the dev environment, pushes it to the Artifact Registry repository, and deploys it as a new Cloud Run revision using the same service account throughout.
The IAM step outside the workflow file
One step lives outside the workflow file itself: some org policies block public access even when "allow unauthenticated" is set on the service. The Cloud Run service needed an explicit IAM binding granting access to all users before doctors could actually reach it.
Key takeaways
- Reuse an existing Workload Identity Federation pool for a new repository by widening the provider's attribute condition, rather than standing up a second identity path.
- A shared service account still needs an explicit role binding scoped to the new repository before it can be impersonated.
- Deploying only on git tags, not every commit, makes tagging the explicit signal that a commit is promotable.
- Vite bakes build-time variables like API URL and version directly into the bundle, so they must be passed as Docker build arguments, not runtime environment variables.
- A two-stage Docker build (Node to build, Nginx to serve) ships only static files in the final image, with no Node toolchain included.
- Public access on Cloud Run can require an explicit IAM binding even with "allow unauthenticated" set, depending on org policy.
Who this is for
Developers setting up or extending a GCP-based CI/CD pipeline, especially teams with an existing backend deployment who want to add a frontend repository without duplicating the identity and trust infrastructure.
Chapters
- 0:00Developing the Medas sepsis and diagnosis frontend
- 0:15Creating the Artifact Registry repository on GCP
- 0:30Sharing Workload Identity Federation pools across backend and frontend repositories
- 0:50Configuring GitHub dev environment secrets and variables
- 1:05Overview of the React & Vite doctor-facing diagnosis component interface
- 1:20Tag-based deployment triggers vs. building on every commit
- 1:35Writing a two-stage Dockerfile using Node and Nginx
- 1:50Building, pushing, and deploying to Cloud Run
- 2:05Setting explicit IAM bindings for doctor access
- 2:20The developer workflow: Git tag and push
Full transcript(auto-generated, with timestamps)
Developing the Medas sepsis and diagnosis frontend
[0:00]Jambo, this is Darill developers push code to meta's aggregation front end. The front end for an AI assisted diagnostic tool doctors used to review sepsis and diagnosis output. Here's everything that had to exist before a push could become a running service, the GCP trust chain, the app itself, and how
Creating the Artifact Registry repository on GCP
[0:16]It all actually gets shipped. Start with somewhere for a built image to live. Create a dedicated artifact registry repository for the front end in the same GCP project and region. The back end already uses project meta's 499,121
Sharing Workload Identity Federation pools across backend and frontend repositories
[0:32]Region assist one. Now the identity path the backend already has a workload identity federation pool set up. No reason to build a second one. List what's there GitHub pool and inside it GitHub provider. The provider currently trusts only the backends repo. Widen its attribute condition to also accept this
Configuring GitHub dev environment secrets and variables
[0:51]One. So both repos can authenticate through the same door. The provider recognizes the repo. The service account still has to agree to be impersonated by it. Bind the shared GitHub actions service account. So this repo's workload identity can act as it one role scoped
Overview of the React & Vite doctor-facing diagnosis component interface
[1:06]To exactly this repository. On the GitHub side, a new environment named dev holding two secrets and seven variables. Neither secret is a longived credential, just the provider path and the service account email. The variables assemble
Tag-based deployment triggers vs. building on every commit
[1:20]The image tag and point the deploy at the right project region and service. Put together that's the whole trust chain. The front-end repo requests a token. The provider recognizes it. The shared service account accepts the impersonation and its existing GCP roles
Writing a two-stage Dockerfile using Node and Nginx
[1:36]Carry it the rest of the way into artifact registry in cloud run. Before the pipeline, the thing the pipeline ships a vite and react front end for doctors reviewing AI assisted sepsis and diagnosis output. Ogates the app. No token, no diagnostic view. Everything
Building, pushing, and deploying to Cloud Run
[1:51]Doctor facing lives under components. Diagnosis editing. Sepsis panels and output table. A dialogue thread. A mic button for voice input. Trust chain ready. The app ready to ship. But nothing tied a code changed to a running service. Every deploy was a manual build
Setting explicit IAM bindings for doctor access
[2:06]On someone's machine. The plan. A tagbased CI/CD pipeline. Push a tag and a container gets built, pushed into the registry already set up and deployed straight to Cloud Run. First design decision. No deploy on every commit. Only a tag dev, stage v, or a bare v for
The developer workflow: Git tag and push
[2:22]Master triggers a build. Tagging is the moment someone decides this commit is promotable, not the moment it was written. The container is two stages. Node builds the vite app. The API URL and version get baked in as build arguments because vite inlines them into the bundle at build time, not read at container runtime. Then a clean enginex image serves only the built disc folder. None of the node tool chain ships in the final image. The workflow authenticates with the identity set up earlier, builds the image with the variables from the dev environment, pushes it to the artifact registry repo created earlier, then deploys it as a new cloud run revision using the same service account the whole way through. End to end tag authenticate, build, push, deploy. One more step lives outside the workflow file. Some org policies block
Public access even with allow an authenticated set. So the cloud run service itself needed an explicit AM binding for all users before doctors could actually reach it. So here's what exists now that didn't before. A shared trust path the front end borrows from the backend instead of duplicating. A two-stage container that ships nothing but static files and engine X and one tagging convention that decides dev stage or master. A developer's whole deploy action after all of this is two lines. Get tag get push. Your turn. If your team already has one repo deploying to GCP through workload identity, don't stand up a second identity path for the next one. Widen the existing provider's condition. Bind the new repos principle to the shared service account and reuse everything else, the registry, the roles, the workflow shape. Push taglive. This is Darel.
More from Humanitarians AI Fellows
2:24Testing Gordy: Running a 5-Stage AI Tool Review | Yatra
3:46CI Checks & Rollback Safety Nets: Guarding Live Deployments | Darshil
2:49The AI Saturation Crisis on LinkedIn | Yatra Rawat
1:59How to Log Your Week with AI (Recap vs Highlight Reel) | Agrima
3:20What is LLM Visibility? Auditing AI Recommendation Bias | Karishma
4:04