Automating BPA with C# in Tabular Editor + GitHub Actions
Building your Power BI CI/CD pipeline with GitHub Actions (Part 2)
This is Part 2 of a series on building a Power BI CI/CD pipeline with GitHub Actions. In Part 1, I shared how you can start building your CI/CD pipeline and run the Best Practice Analyzer (BPA) with both standard and custom rulesets.
In this post, you’ll learn how to set up a more advanced BPA process, along with key lessons and practical insights to avoid common pitfalls.
Let’s Fix the BPA Bottleneck
One major issue with the default BPA approach is that you must re-run the analyzer for each Severity 3 issue — assuming you've already resolved previous ones. This makes the process repetitive and inefficient.
The better alternative I found is using a custom macro—a C# script executed via Tabular Editor—which consolidates all findings into one output, regardless of how many issues exist. This output can then be exported and further analyzed quickly. The main benefits of this solution are:
✅ Single consolidated run: No need to run BPA multiple times for each issue — one script run captures everything.
✅ Structured output: Results are exported as a clean, tabular CSV file that’s easy to parse and automate further.
✅ Full custom ruleset support: You can fully define and control your BPA rules, unlike the limited default options.
Solution Overview
If you like this approach, you don’t have to troubleshoot it all yourself. You can simply go to the GitHub repo and try out my version. Compared to the previous scenario discussed in my previous post all you need is:
A custom BPA rules file (We used one in the previous demo. This time, I’ll increase the rule count from 1 to 10 so we get deeper insight into our model — but don’t get overwhelmed by the output!)
The custom C# macro script.
A tiny modification in the GitHub Actions YAML file.
Previously, we used the built-in -A
(analyze) flag when running Tabular Editor and reference the BPA rules directly. Now, we’ll switch to -S
to run a script file and invoke the scritp itself.
What to Pay Attention to in Your Script
Custom Ruleset Location
The
GetCollectionFromFile
method requires two arguments: the base path and the filename.This can be tricky if you rely on
file:
paths or GitHub Actions artifacts. Make sure you understand the working directory in your pipeline.
Using Only the Custom Ruleset
If you don’t configure this part correctly, TE will fall back to using default rules. Figuring this out took a lot of time, effort, and trial and error, but I finally managed to find the solution.
Use
includeExternalRules: true
and set all others tofalse
.
JSON file must be valid
Your custom BPA
.json
file must be properly structured.You can add new fields, but none of the values can be
NaN
or invalid.Otherwise, the script will fail silently—making it seem like your model has no issues at all. Sounds nice, right? But let’s stay realistic.
That’s it! 🎉
You just ran a fully custom BPA check via Tabular Editor and exported a complete report as a CSV file—all in one step.
While experimenting with this setup, I learned a few key lessons:
⚠️ Silent Failures in GitHub Actions
Tabular Editor (TE) may fail silently without displaying an obvious error. Even if it generates an output file, it doesn't mean everything worked correctly—you have to verify the results.
🧪 Debugging Is Harder
Since TE doesn’t always throw explicit errors, validating your script’s behavior becomes crucial. Logs might appear clean, but something may still be broken under the hood.
💻 Always Test Locally First
You're using the same Tabular Editor CLI on your local machine as GitHub Actions does. Running the script locally is significantly faster, doesn’t require committing every change, and skips the wait for the virtual environment to spin up. This is a huge time-saver when you're experimenting.
That said—be prepared: sometimes it’ll work locally, but still fail on GA due to environment differences.
Hopefully this gives you a more efficient, scalable way to integrate BPA into your Power BI workflows — without the repetition or mystery failures.
Got feedback or want to dive deeper?
If you're curious about the technical challenges I ran into while creating this workflow — or just want to share your thoughts — feel free to leave a comment or connect with me on LinkedIn.
What’s Coming Next
In the next posts, I’ll cover:
🔍 How to analyze the output of this script automatically.
🤖 How to build an automated process that makes decisions based on the BPA output when a Pull Request is submitted.
🛠️ How to always run your script from the
main
branch.🗃️ How to set up a central repository so you maintain one source of truth.
🧰 How to create a repository template for setting up future reports with the same rules and workflows.