<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Gemini on Dominik Jaro</title><link>https://dominikjaro.pages.dev/tags/gemini/</link><description>Recent content in Gemini on Dominik Jaro</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>Dominik Jaro</copyright><lastBuildDate>Tue, 22 Sep 2026 13:29:11 +0100</lastBuildDate><atom:link href="https://dominikjaro.pages.dev/tags/gemini/index.xml" rel="self" type="application/rss+xml"/><item><title>📚 Automating Repository Documentation with OpenWiki and GCP Cloud Build</title><link>https://dominikjaro.pages.dev/p/automating-repository-documentation-with-openwiki-and-gcp-cloud-build/</link><pubDate>Tue, 22 Sep 2026 00:00:00 +0000</pubDate><guid>https://dominikjaro.pages.dev/p/automating-repository-documentation-with-openwiki-and-gcp-cloud-build/</guid><description>&lt;img src="https://dominikjaro.pages.dev/p/automating-repository-documentation-with-openwiki-and-gcp-cloud-build/openwiki.png" alt="Featured image of post 📚 Automating Repository Documentation with OpenWiki and GCP Cloud Build" />&lt;p>Keeping repository documentation up to date is a task that often gets deprioritized as codebases evolve. To solve this, I recently automated our documentation workflow across several application repositories using &lt;strong>&lt;a class="link" href="https://github.com/langchain-ai/openwiki" target="_blank" rel="noopener"
>OpenWiki&lt;/a>&lt;/strong>.&lt;/p>
&lt;p>For our initial rollout, we opted to skip the OpenWiki visualizer and focus strictly on generating and committing updated &lt;code>.md&lt;/code> files directly inside the repositories whenever changes land on our staging branch.&lt;/p>
&lt;p>Here is how I designed and built this pipeline using &lt;strong>GCP Cloud Build&lt;/strong>, &lt;strong>Terraform&lt;/strong>, and &lt;strong>Gemini Enterprise&lt;/strong>.&lt;/p>
&lt;hr>
&lt;h2 id="-architecture--security-setup">🏗️ Architecture &amp;amp; Security Setup
&lt;/h2>&lt;p>When implementing LLM-powered tools into CI/CD pipelines, cost tracking and access control are critical considerations.&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Dedicated GCP Project:&lt;/strong> Since OpenWiki doesn&amp;rsquo;t currently support custom resource labels on API calls (I’ve submitted a feature request for this on the OpenWiki repo), I isolated this setup into its own dedicated GCP project. This ensures clean cost attribution and isolated billing metrics.&lt;/li>
&lt;li>&lt;strong>Model Selection:&lt;/strong> The pipeline uses the &lt;code>gemini-enterprise 3.6-flash&lt;/code> model for lightweight, fast, and cost-effective documentation generation.&lt;/li>
&lt;li>&lt;strong>Least Privilege IAM:&lt;/strong> The project runs on a dedicated Service Account with strictly scoped permissions required only for Cloud Build execution and API access.&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h2 id="-step-by-step-implementation">🛠️ Step-by-Step Implementation
&lt;/h2>&lt;h3 id="1-custom-docker-container">1. Custom Docker Container
&lt;/h3>&lt;p>OpenWiki needs both its CLI dependencies and Git to interact with the repository. I built a lightweight, specialized Docker image containing both &lt;code>openwiki&lt;/code> and &lt;code>git-cli&lt;/code> to keep the pipeline execution fast.&lt;/p>
&lt;h3 id="2-infrastructure-as-code-terraform">2. Infrastructure as Code (Terraform)
&lt;/h3>&lt;p>Using Terraform, I provisioned:&lt;/p>
&lt;ul>
&lt;li>The isolated GCP Project and enabled required APIs (Vertex AI / Cloud Build).&lt;/li>
&lt;li>The dedicated Service Account and IAM roles following the principle of least privilege.&lt;/li>
&lt;li>Inline &lt;strong>GCP Cloud Build triggers&lt;/strong> attached to our application repositories.&lt;/li>
&lt;/ul>
&lt;h3 id="3-the-cloud-build-pipeline">3. The Cloud Build Pipeline
&lt;/h3>&lt;p>The Cloud Build trigger fires automatically whenever code is pushed to or created on our staging branch. The pipeline step checks out the target branch, runs OpenWiki, and commits the updated &lt;code>.md&lt;/code> documentation back to origin.&lt;/p>
&lt;p>Here is the core inline build step used in the Cloud Build trigger:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-yaml" data-lang="yaml">&lt;span class="line">&lt;span class="cl">- &lt;span class="nt">name&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;gcr.io/your-project/openwiki-runner:latest&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">entrypoint&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;sh&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="nt">args&lt;/span>&lt;span class="p">:&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="s1">&amp;#39;-c&amp;#39;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>- &lt;span class="p">|&lt;/span>&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> set -e
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> TARGET_BRANCH=&amp;#34;${BRANCH_NAME}&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> if [ -z &amp;#34;$TARGET_BRANCH&amp;#34; ]; then
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> TARGET_BRANCH=&amp;#34;${_HEAD_BRANCH}&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> fi
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> echo &amp;#34;Checking out PR source branch: $TARGET_BRANCH&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git remote set-url origin &amp;#34;git@github.com:${REPO_FULL_NAME}.git&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git fetch origin &amp;#34;$TARGET_BRANCH&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git checkout &amp;#34;$TARGET_BRANCH&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> echo &amp;#34;Running OpenWiki documentation generation...&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> openwiki code --update --print
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git config user.email &amp;#34;${_GIT_USER_EMAIL}&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git config user.name &amp;#34;${_GIT_USER_NAME}&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git add openwiki
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git commit -m &amp;#34;docs(openwiki): auto-update documentation [skip ci]&amp;#34; || true
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="sd"> git push origin &amp;#34;$TARGET_BRANCH&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>(Note: SSH key provisioning and GitHub authentication details are handled separately outside of this build step.)&lt;/p>
&lt;h2 id="-key-takeaways">🎯 Key Takeaways
&lt;/h2>&lt;p>&lt;strong>Zero Developer Friction:&lt;/strong> Developers don&amp;rsquo;t need to manually run CLI commands to update docs—it happens automatically in CI/CD on staging pushes.&lt;/p>
&lt;p>&lt;strong>Cost Isolation:&lt;/strong> Until OpenWiki supports granular labeling natively, running LLM tasks in a dedicated GCP project is a clean workaround for cost management.&lt;/p>
&lt;p>&lt;strong>Preventing Infinite Loops:&lt;/strong> Adding [skip ci] to the automated commit message prevents Cloud Build from recursively triggering itself on doc updates.&lt;/p></description></item></channel></rss>