<?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>DEV Community: Denis Shevelev</title>
    <description>The latest articles on DEV Community by Denis Shevelev (@denis_shevelev_79caec3695).</description>
    <link>https://dev.to/denis_shevelev_79caec3695</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%2F3801620%2F38316728-d62f-4641-bad0-ffef9fb9f5eb.png</url>
      <title>DEV Community: Denis Shevelev</title>
      <link>https://dev.to/denis_shevelev_79caec3695</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/denis_shevelev_79caec3695"/>
    <language>en</language>
    <item>
      <title>CI/CD for BigQuery Views</title>
      <dc:creator>Denis Shevelev</dc:creator>
      <pubDate>Mon, 02 Mar 2026 20:58:40 +0000</pubDate>
      <link>https://dev.to/denis_shevelev_79caec3695/cicd-for-bigquery-views-51jg</link>
      <guid>https://dev.to/denis_shevelev_79caec3695/cicd-for-bigquery-views-51jg</guid>
      <description>&lt;p&gt;&lt;strong&gt;How I Automated What I Was Tired of Doing Manually&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm a freelance data analyst. I work with multiple clients simultaneously: building dashboards in Power BI and Tableau, writing SQL queries, and automating reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I Got Here&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of my projects involves web analytics. The data lives in BigQuery, and I've built a layer of views on top of it for Power BI. As the project grew, I needed a way to roll back to previous versions, hand off work to clients, and be sure I was always working with the latest version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Solution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Git becomes the single source of truth. All SQL code is stored in a repository, and CI/CD automatically applies changes to BigQuery on every commit. Sounds like something only DevOps engineers do? This article will walk you through the setup process step by step.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What You'll Need:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• GitLab (free account is enough)&lt;br&gt;
• Google Cloud Console&lt;br&gt;
• Google Cloud project with BigQuery&lt;br&gt;
• About 2 hours for the initial setup&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's Covered in This Article:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Setting up access (GitLab Token + GCP Service Account)&lt;/li&gt;
&lt;li&gt; Repository structure for SQL files&lt;/li&gt;
&lt;li&gt; CI/CD pipeline (YAML configuration)&lt;/li&gt;
&lt;li&gt; Python integration script&lt;/li&gt;
&lt;li&gt; Runner setup&lt;/li&gt;
&lt;li&gt; Testing the workflow&lt;/li&gt;
&lt;/ol&gt;



&lt;p&gt;Part 1: &lt;/p&gt;
&lt;h2&gt;
  
  
  Setting Up Access
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before You Click — Let's Understand What's Happening&lt;/strong&gt;&lt;br&gt;
Our CI/CD pipeline is a program that runs on GitLab's server. It needs to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Read&lt;/strong&gt; the changed SQL files from your repository&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Write&lt;/strong&gt; those SQL queries to BigQuery&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The problem: GitLab's server knows nothing about your repository, let alone your BigQuery. It needs "keys" — proof that you've authorized it to act on your behalf.&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%2Fmlw89hhk0opvw4m9gggc.jpg" 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%2Fmlw89hhk0opvw4m9gggc.jpg" alt=" " width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two different keys for two different systems. Let's break down each one.&lt;/p&gt;

&lt;p&gt;Block A: &lt;/p&gt;
&lt;h2&gt;
  
  
  GitLab Access Token
&lt;/h2&gt;

&lt;p&gt;First, we need to generate a token for programmatic access to the repository. There are two options (Personal Token and  Project Token) — let's look at each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;which one should you choose?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Project Token is tied to the repository and works better for teams. But for your first setup, a Personal Token is simpler — fewer steps, less room for mistakes. Once everything is working, you can migrate to a Project Token. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to create a Personal Token:&lt;/em&gt;&lt;br&gt;
1․ Click your Avatar → Preferences → Personal access tokens&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%2Fji5zsb0vbtek7veg4eci.jpg" 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%2Fji5zsb0vbtek7veg4eci.jpg" alt=" " width="800" height="166"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2․ Click &lt;strong&gt;Add new token&lt;/strong&gt;&lt;br&gt;
3․ Fill in the form: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Token name: cicd-bigquery-reader (use a clear name)&lt;/li&gt;
&lt;li&gt;  Expiration: I recommend 1 year&lt;/li&gt;
&lt;li&gt;  Scopes: &lt;strong&gt;api, read_api, read_repository&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;4․ Click &lt;strong&gt;Create personal access token&lt;/strong&gt;&lt;br&gt;
5․ &lt;strong&gt;Copy the token&lt;/strong&gt; — it's only shown once&lt;/p&gt;

&lt;p&gt;&lt;code&gt;glpat-xxxxxxxxxxxxxxxxxxxx  ← save this somewhere safe&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;How to create a Project Token:&lt;/em&gt;&lt;br&gt;
Note: Project Tokens may not be available in your GitLab setup (see how to fix this below)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open your project in GitLab&lt;/li&gt;
&lt;li&gt; Go to &lt;strong&gt;Settings → Access Tokens&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Add new token&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Fill in the form just like you did for the Personal Token above&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Create project access token&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2F7qysfyw5ddbmyzz2x5gy.jpg" 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%2F7qysfyw5ddbmyzz2x5gy.jpg" alt=" " width="800" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;6․    Copy the token — GitLab will never show it again&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%2F4xrpfj0fvqy0tojgpts8.jpg" 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%2F4xrpfj0fvqy0tojgpts8.jpg" alt=" " width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done, the token is created. Save it somewhere safe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do if you can't create a Project Token:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On GitLab's free plan, Project Access Tokens may be disabled at the group level.&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%2F4u8gm65g71fdtpiw25ps.jpg" 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%2F4u8gm65g71fdtpiw25ps.jpg" alt=" " width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this case, you can create a new project in your personal namespace (outside the group)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a project in your personal namespace&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 1: Click &lt;strong&gt;+&lt;/strong&gt; in GitLab's top panel → &lt;strong&gt;New project/repository&lt;/strong&gt;&lt;br&gt;
Step 2: Select Create blank project&lt;br&gt;
Step 3: Fill in the form:&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%2Frb6b001pdevrh2t1jlav.jpg" 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%2Frb6b001pdevrh2t1jlav.jpg" alt=" " width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;• Project name: bigquery_views_test (or your name)&lt;br&gt;
• In the dropdown list select your &lt;strong&gt;username&lt;/strong&gt; (not the group!)&lt;br&gt;
• Project URL: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Should look like: gitlab.com/&amp;lt; **User name** &amp;gt;/&amp;lt; **Project name** &amp;gt;&lt;br&gt;
❌ Not like this: gitlab.com/&amp;lt; **Group name** &amp;gt;/...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;• Visibility level: &lt;strong&gt;Private&lt;/strong&gt; (recommended for work projects)&lt;br&gt;
• ✓ &lt;strong&gt;Initialize repository with a README&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 4: Click &lt;strong&gt;Create project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now you have access to create a Project Token&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%2Feglekuotkyjq5jt1t0u5.jpg" 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%2Feglekuotkyjq5jt1t0u5.jpg" alt=" " width="800" height="296"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Block B: &lt;/p&gt;
&lt;h2&gt;
  
  
  Google Cloud Service Account
&lt;/h2&gt;

&lt;p&gt;Why you need it: A service account is a "technical user" in Google Cloud. Unlike your personal account, it has no password or 2FA — just a JSON key. Perfect for automation.&lt;/p&gt;

&lt;p&gt;Open &lt;a href="https://console.cloud.google.com/" rel="noopener noreferrer"&gt;Google Cloud Console&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;1 At the top, select the correct project (the one with your BigQuery) &lt;br&gt;
&lt;em&gt;Rule: Create the service account in the same GCP project where your BigQuery lives — the one where you'll be deploying views.&lt;/em&gt;&lt;br&gt;
2  Verify that the URL shows the correct project-id&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%2F232gl1z6yk4hosu49ik2.jpg" 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%2F232gl1z6yk4hosu49ik2.jpg" alt=" " width="800" height="306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3 Now navigate to: &lt;strong&gt;IAM &amp;amp; Admin&lt;/strong&gt; → &lt;strong&gt;Service Accounts&lt;/strong&gt; → &lt;strong&gt;Create Service Account&lt;/strong&gt;&lt;br&gt;
4    Fill in the form:&lt;br&gt;
• Name: gitlab-cicd-bigquery (This generates an email like: &lt;a href="mailto:gitlab-cicd-bigquery@your-project.iam.gserviceaccount.com"&gt;gitlab-cicd-bigquery@your-project.iam.gserviceaccount.com&lt;/a&gt;)&lt;br&gt;
• Description: GitLab CI/CD for BigQuery views deployment&lt;br&gt;
5  Click &lt;strong&gt;Create and Continue&lt;/strong&gt;&lt;br&gt;
6 Grant access: select &lt;strong&gt;BigQuery Data Editor&lt;/strong&gt;&lt;br&gt;
7 &lt;strong&gt;Continue&lt;/strong&gt; and &lt;strong&gt;Done&lt;/strong&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%2F9a4veqsgvvfzbphwlvej.jpg" 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%2F9a4veqsgvvfzbphwlvej.jpg" alt=" " width="800" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Now let's create the JSON key:&lt;/em&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Click on the service account you just created&lt;/li&gt;
&lt;li&gt; Go to &lt;strong&gt;Keys&lt;/strong&gt; tab → &lt;strong&gt;Add Key&lt;/strong&gt; → &lt;strong&gt;Create new key&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Choose &lt;strong&gt;JSON&lt;/strong&gt; format&lt;/li&gt;
&lt;li&gt; The file downloads automatically — save it somewhere safe!&lt;/li&gt;
&lt;/ol&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%2Fvv7b4bmmfzx7xvo69b5c.jpg" 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%2Fvv7b4bmmfzx7xvo69b5c.jpg" alt=" " width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The key looks something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
"type": "service_account",
 "project_id": "your-project", 
"private_key_id": "abc123...", 
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEv...", ← this is what we need
"client_email": "gitlab-cicd-bigquery@your-project.iam.gserviceaccount.com", 
... 
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store the key somewhere safe. No need to modify it!&lt;/p&gt;




&lt;p&gt;Block C: &lt;/p&gt;

&lt;h2&gt;
  
  
  CI/CD Variables in GitLab
&lt;/h2&gt;

&lt;p&gt;Hardcoding secrets in code is a bad idea — anyone with repository access can see your keys. To avoid this, we'll create a CI/CD variable in GitLab. These variables are stored separately from the code, masked in logs, and only accessible during pipeline execution.&lt;/p&gt;

&lt;p&gt;Before creating the variable, we need to prepare the private_key from the JSON file. The problem is that private_key contains \n characters (line breaks), and GitLab can't mask strings containing \n.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What to do:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;• Copy the private_key value from the JSON file:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBg… T2ZDRX61+y \nWmi...A3C\n1YIw Sb…K0/jQqFRHXPKc=\n-----END PRIVATE KEY-----\n "&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;• Remove the wrapper — delete these parts: "-----BEGIN PRIVATE KEY-----\n and \n-----END PRIVATE KEY-----\n"&lt;br&gt;
• Keep only the key "body":&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MIIEvQIBADANBg…T2ZDRX61+y\nWmi...A3C\n1YIwSb…K0/jQqFRHXPKc=&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;• Replace all &lt;strong&gt;\n&lt;/strong&gt; with &lt;strong&gt;@&lt;/strong&gt; (there are many — use find &amp;amp; replace, don't do it manually)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;MIIEvQIBADANBg…T2ZDRX61+y@Wmi...A3C@1YIwSb…K0/jQqFRHXPKc=&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;• Make sure there are no spaces at the beginning or end of the string&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to add a variable&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go back to GitLab, open the needed project&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;CI/CD&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Expand the &lt;strong&gt;Variables&lt;/strong&gt; section&lt;/li&gt;
&lt;li&gt; Click &lt;strong&gt;Add variable&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Fill in: 
&lt;strong&gt;Visibility&lt;/strong&gt;: ✓ Mask variable; &lt;strong&gt;Flags&lt;/strong&gt;: ✓ Protect variable; &lt;strong&gt;Key&lt;/strong&gt;: variable name (for example, BQ_KEY); &lt;strong&gt;Value&lt;/strong&gt;: the prepared key "body"&lt;/li&gt;
&lt;li&gt; Add variable&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Part 2: &lt;/p&gt;

&lt;h2&gt;
  
  
  The YAML Configuration File
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What it's for&lt;/strong&gt;: This is a script for GitLab CI/CD — it tells GitLab what to do when you commit to the repository.&lt;/p&gt;

&lt;p&gt;Now we need to create a YAML file for our CI/CD pipeline. Create a file called .gitlab-ci.yml in the root of your repository.&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%2F9lsdc9evschel0em0mgt.jpg" 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%2F9lsdc9evschel0em0mgt.jpg" alt=" " width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and tell GitLab where to find it. To do this, go to &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;CI/CD&lt;/strong&gt; → &lt;strong&gt;General&lt;/strong&gt; pipelines and enter the path in &lt;strong&gt;CI/CD configuration file&lt;/strong&gt; field. However, if you create &lt;strong&gt;.gitlab-ci.yml&lt;/strong&gt; in the root of your repository, GitLab will find it automatically — no extra configuration needed.&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%2Fes451hoyxkz21geecuri.jpg" 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%2Fes451hoyxkz21geecuri.jpg" alt=" " width="800" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll create a very simple pipeline with just one stage — deploying a view to BigQuery. But you can make it as complex as you need! For example, you could add stages for query validation or other checks.&lt;br&gt;
Our pipeline will run whenever you push to the main branch. Here's what the YAML code looks like:&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%2Fkyzsh6g3ffo2g4yq9rwb.jpg" 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%2Fkyzsh6g3ffo2g4yq9rwb.jpg" alt=" " width="588" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can download the file &lt;a href="https://github.com/DenisShevele78/articles-materials/blob/main/bigquery-cicd-tutorial/.gitlab-ci.yml" rel="noopener noreferrer"&gt;here&lt;/a&gt;, and &lt;a href="https://docs.gitlab.com/ee/ci/yaml/" rel="noopener noreferrer"&gt;here&lt;/a&gt; you'll find the full documentation of all YAML commands and features for GitLab.&lt;/p&gt;




&lt;p&gt;Part 3: &lt;/p&gt;

&lt;h2&gt;
  
  
  The BigQuery Deployment Script
&lt;/h2&gt;

&lt;p&gt;Let's create the &lt;strong&gt;folder structure&lt;/strong&gt; in GitLab&lt;br&gt;
Step 1: Open your repository in GitLab&lt;br&gt;
Step 2: Click &lt;strong&gt;+&lt;/strong&gt; button → &lt;strong&gt;New file&lt;/strong&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%2F18gctusagm08ysdvg76w.jpg" 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%2F18gctusagm08ysdvg76w.jpg" alt=" " width="800" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 3: In Filename field, enter the full path at once:&lt;br&gt;
&lt;code&gt;projects/ &amp;lt;project&amp;gt;/&amp;lt;dataset&amp;gt; /views/.gitkeep&lt;/code&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%2Fx4udvyji749e4uggef57.jpg" 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%2Fx4udvyji749e4uggef57.jpg" alt=" " width="468" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where  and  are the actual names of your project and dataset in BigQuery (where your views are stored). Git doesn't store empty folders, so .gitkeep is an empty placeholder file that keeps the folder in the repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now let's add a SQL file&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Step 1: Navigate to the folder projects///views/&lt;br&gt;
Step 2: Click  &lt;strong&gt;+&lt;/strong&gt;  → &lt;strong&gt;New file&lt;/strong&gt;&lt;br&gt;
Step 3: The file name should be your view's name&lt;br&gt;
&lt;em&gt;Note: The view doesn't have to exist in BigQuery yet&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Step 4: Create a file following these repository code organization rules:&lt;br&gt;
• View code is stored in files with the .sql extension&lt;br&gt;
• Views are located at: &lt;br&gt;
&lt;code&gt;projects/&amp;lt;BQ Project&amp;gt;/&amp;lt;BQ Dataset&amp;gt;/views/&amp;lt;View name&amp;gt;.sql&lt;/code&gt;&lt;br&gt;
• File name (without extension) must match the view name&lt;br&gt;
• View code must start with CREATE OR REPLACE VIEW&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%2Fynqaj9yknuix9otpzq0s.jpg" 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%2Fynqaj9yknuix9otpzq0s.jpg" alt=" " width="800" height="372"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The script that handles deployment to production performs a few simple checks and writes all modified views to BigQuery.&lt;/p&gt;

&lt;p&gt;You can find the full script with comments &lt;a href="https://github.com/DenisShevele78/articles-materials/blob/main/bigquery-cicd-tutorial/cicd_validate.py" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;Part 4: &lt;/p&gt;

&lt;h2&gt;
  
  
  GitLab Runner
&lt;/h2&gt;

&lt;p&gt;A Runner is an application that executes the jobs defined in your .gitlab-ci.yml. When you commit, GitLab sends the job to a runner, which then runs your script.&lt;br&gt;
You commit → GitLab → Runner executes the script → View updates in BigQuery&lt;/p&gt;

&lt;p&gt;Two options: Shared or self-hosted&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Shared Runners - Already set up, no action needed&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Project Runner - Full control, runs on your server&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Option 1:&lt;/u&gt; &lt;strong&gt;Shared Runners&lt;/strong&gt; (recommended to start)&lt;br&gt;
&lt;em&gt;Good news: Shared Runners are already enabled on GitLab.com!&lt;/em&gt;&lt;br&gt;
How to check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go to &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;CI/CD&lt;/strong&gt; → expand &lt;strong&gt;Runners&lt;/strong&gt; section&lt;/li&gt;
&lt;li&gt; Click on &lt;strong&gt;Instance&lt;/strong&gt; tab&lt;/li&gt;
&lt;li&gt; If you see runners listed (e.g., "117") — you're all set&lt;/li&gt;
&lt;/ol&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%2Fxbkcz5wi7dkfvxqryt7y.jpg" 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%2Fxbkcz5wi7dkfvxqryt7y.jpg" alt=" " width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Done! You don't need to install anything. When you commit, one of the Shared Runners will automatically execute your pipeline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared Runners security:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Each pipeline runs in an isolated container that is deleted after completion. Your BQ_KEY is masked in logs. For most projects, this is secure enough.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Option 2:&lt;/u&gt; &lt;strong&gt;Project Runner&lt;/strong&gt; (if you need your own)&lt;br&gt;
The final step is creating a &lt;a href="https://docs.gitlab.com/runner/" rel="noopener noreferrer"&gt;runner&lt;/a&gt; — an application that will execute the CI/CD process.&lt;br&gt;
To create a runner, go to &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;CI/CD&lt;/strong&gt; → &lt;strong&gt;Runners&lt;/strong&gt; → &lt;strong&gt;Create project runner&lt;/strong&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%2Fidnx94rbfwuoxt2xhrnu.jpg" 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%2Fidnx94rbfwuoxt2xhrnu.jpg" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Filling out the form:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Tags&lt;/strong&gt; (field at the top) 
&lt;em&gt;Leave it EMPTY (don't enter anything)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;✓ Run untagged jobs&lt;/strong&gt; 
&lt;em&gt;MUST be checked! (Without this, the runner won't execute your jobs)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Runner description&lt;/strong&gt; 
&lt;em&gt;Enter: Windows Runner (or your OS)&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt; Other checkboxes: Paused — do NOT check; Protected — do NOT check;  Lock to current projects — do NOT check&lt;/li&gt;
&lt;li&gt; Click  &lt;strong&gt;Create runner&lt;/strong&gt; button&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You need to download and install the runner. A detailed description of runners and their setup process can be found, for example, &lt;a href="https://docs.gitlab.com/runner/install/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. (I chose GitLab Runner; below are the steps for Windows OS)&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Step A:&lt;/u&gt; &lt;strong&gt;Downloading GitLab Runner&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Open PowerShell as Administrator: Press &lt;strong&gt;Win + X&lt;/strong&gt; → Select &lt;strong&gt;Terminal (Admin)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Create a folder:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the PowerShell window in Terminal (Admin) mode, enter:&lt;br&gt;
• Create folder&lt;br&gt;
&lt;code&gt;New-Item -ItemType Directory -Path "C:\GitLab-Runner"&lt;/code&gt;&lt;br&gt;
• Navigate to the folder&lt;br&gt;
&lt;code&gt;cd C:\GitLab-Runner&lt;/code&gt;&lt;br&gt;
• Download gitlab-runner.exe&lt;br&gt;
&lt;code&gt;Invoke-WebRequest -Uri "https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-windows-amd64.exe" -OutFile "gitlab-runner.exe"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If the exe file appears in the folder on your computer — the file was downloaded successfully!&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Step B:&lt;/u&gt; &lt;strong&gt;Registering the Runner in GitLab&lt;/strong&gt;&lt;br&gt;
Now you need to register the runner using a token from GitLab.&lt;br&gt;
Go back to GitLab. Open the registration instructions page (where you were before):&lt;br&gt;
• &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;CI/CD → Runners&lt;/strong&gt; → find the created runner&lt;br&gt;
Or you should have the &lt;strong&gt;Register Windows Runner runner&lt;/strong&gt; page open&lt;/p&gt;

&lt;p&gt;In GitLab on the Step 1 page: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the &lt;strong&gt;copy&lt;/strong&gt; button to the right of the command&lt;/li&gt;
&lt;li&gt;This will copy the entire command with the token&lt;/li&gt;
&lt;/ul&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%2Fgdjeciipxzz1e2l2a79k.jpg" 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%2Fgdjeciipxzz1e2l2a79k.jpg" alt=" " width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Step C&lt;/u&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Go back to PowerShell (should be open in C:\GitLab-Runner)&lt;/li&gt;
&lt;li&gt; Paste the copied command &lt;/li&gt;
&lt;li&gt; Press Enter&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The first question will appear:&lt;br&gt;
&lt;code&gt;Enter the GitLab instance URL (for example, https://gitlab.com/):&lt;/code&gt;&lt;br&gt;
&lt;code&gt;[https://gitlab.com]:&lt;/code&gt;&lt;br&gt;
Your answer: &lt;br&gt;
&lt;code&gt;Just press Enter (uses the default value)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The second question will appear:&lt;br&gt;
&lt;code&gt;Enter a name for the runner. This is stored only in the local config.toml file: [your_computer_name]&lt;/code&gt;&lt;br&gt;
Your answer (the name of the runner created in the previous step):&lt;br&gt;
&lt;code&gt;Windows Runner&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The third question will appear:&lt;br&gt;
&lt;code&gt;Enter an executor: custom, docker, ...&lt;/code&gt;&lt;br&gt;
Your answer:&lt;br&gt;
&lt;code&gt;shell&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Explanation: shell = the runner will execute commands via PowerShell/CMD&lt;/em&gt; &lt;em&gt;on your computer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Alternatives:&lt;br&gt;
• docker — runs in Docker containers (requires Docker Desktop)&lt;br&gt;
• custom — custom configuration&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After entering, you should see:&lt;br&gt;
&lt;code&gt;Runner registered successfully …&lt;br&gt;
PS C:\GitLab-Runner&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Runner successfully registered!&lt;/p&gt;

&lt;p&gt;Command 1: &lt;strong&gt;Install the service&lt;/strong&gt;&lt;br&gt;
In PowerShell (where you are now) run:&lt;br&gt;
&lt;code&gt;.\gitlab-runner.exe install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Information about the platform and runner version will appear&lt;/p&gt;

&lt;p&gt;Command 2: &lt;strong&gt;Start the service&lt;/strong&gt;&lt;br&gt;
Run the final command:&lt;br&gt;
&lt;code&gt;.\gitlab-runner.exe start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A similar message with platform and runner version information will appear&lt;/p&gt;

&lt;p&gt;Service started successfully!&lt;/p&gt;

&lt;p&gt;After the runner is created and registered, make sure it's running. On the CI/CD settings page in the Runners section, your runner should have the status "online."&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%2Fq378e5mtfdxc6rrdxdf0.jpg" 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%2Fq378e5mtfdxc6rrdxdf0.jpg" alt=" " width="800" height="375"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final test&lt;/strong&gt;: Let's verify it works.&lt;/p&gt;

&lt;p&gt;Let's make sure the pipeline runs on your Windows Runner!&lt;br&gt;
As long as Shared Runners are enabled, they may intercept the job&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disable Shared Runners&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In your project: &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;CI/CD&lt;/strong&gt; → &lt;strong&gt;Runners&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt; Go to the Instance tab&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Turn off&lt;/strong&gt; the option &lt;strong&gt;Turn on instance runners for this project&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&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%2F2pscpvw39dg5urjqde8p.jpg" 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%2F2pscpvw39dg5urjqde8p.jpg" alt=" " width="800" height="319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Instructions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; In your project, open any SQL file in projects/.../views/&lt;/li&gt;
&lt;li&gt; Click Edit (pencil icon)&lt;/li&gt;
&lt;li&gt; Make any change to the file&lt;/li&gt;
&lt;li&gt; Commit changes&lt;/li&gt;
&lt;li&gt; Navigate to: Build → Pipelines&lt;/li&gt;
&lt;li&gt; Open the latest pipeline → validate job&lt;/li&gt;
&lt;li&gt; Check the log — you should see: 
&lt;code&gt;Running with gitlab-runner 18.9.0 (...) on Windows Runner z12DMWWg, system ID: ... Preparing the "shell" executor&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&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%2Fvogpbrahx3s0g89wxvbi.jpg" 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%2Fvogpbrahx3s0g89wxvbi.jpg" alt=" " width="800" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the result should look like&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If everything is set up correctly, when you merge a branch (i.e., push to master), a running job will appear in the Jobs tab in GitLab. The list of completed jobs looks like this:&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%2Fyrk60ytxksy0hx7421gm.jpg" 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%2Fyrk60ytxksy0hx7421gm.jpg" alt=" " width="800" height="156"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In BigQuery, in the Views section, the updated view will appear with SQL code matching the latest commit in GitLab. In this example, the SQL query for creating a view in BigQuery was executed successfully — exactly what we were aiming for!&lt;/p&gt;

</description>
      <category>gitlab</category>
      <category>cicd</category>
      <category>python</category>
    </item>
  </channel>
</rss>
