# Anyone successfully using version control and CI/CD for automation in your company?

**URL:** <https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294>\
**Category:** General Discussion\
**Created:** [July 9, 2025, 9:40pm UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294 "2025-07-09T21:40:20Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Guillermo\_Piedra](https://avatars.discourse-cdn.com/v4/letter/g/ce73a5/32.png) [@Guillermo\_Piedra](https://forum.inductiveautomation.com/u/Guillermo_Piedra)\
**Post date:** [July 9, 2025, 9:40pm UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/1 "2025-07-09T21:40:20Z")

</div>

We're dabbling with the idea of versioning our projects by using either Github, Bitbucket and Azure DevOps as our repo service by referencing this article.

> **[Ignition 8 Deployment Best Practices](https://inductiveautomation.com/resources/article/ignition-8-deployment-best-practices)**
>
> Inductive Automation provides this helpful guide for deploying Ignition applications. The guide offers Ignition 8 best practices for setting up development and testing workflow.

I wanted to know if there are any real cases of Git, version control and CI/CD pipelines out there in production. Have any of you successfully implemented it with client projects? What was the result? And how did you accomplish it? Also if you have any recommendation on which service works best please feel free to share. Thanks in advance!

---

<div class="post-metadata">

**Author:** ![Eduardo\_Alves](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@Eduardo\_Alves](https://forum.inductiveautomation.com/u/Eduardo_Alves)\
**Post date:** [July 10, 2025, 1:12am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/2 "2025-07-10T01:12:51Z")

</div>

At my company, we're not using CI/CD with Ignition yet, but we've been using Git for over a year now. It's absolutely fantastic to have a SCADA project where you can use Git and see exactly what was changed. Here are a few important points based on our experience:

- I had to create a pretty complex `.gitignore` file to exclude all the unnecessary folders and keep only the ones for our main project and a custom theme we created.
- Inside each view, there's a `resource.json` file that contains a hash calculated based on `view.json` and `thumbnail.png`. Just opening the view changes this hash, so Git sees it as a modification. You always have to discard those changes to avoid cluttering your version history.
- Definitely use a visual tool like VS Code to manage your version control — it helps a lot.
- Unfortunately, tags are stored in an SQLite database, which makes it hard to track changes. In my case, I have tens of thousands of tags, and exporting them to a file is just not practical. So I created a folder in the project where I keep version control of the UDTs separately from Ignition.
- Another tricky part is the image database — saved images are stored in a database, which makes them hard to manage.
- One of the best things about using Git is the ability to work concurrently on different developments. I highly recommend using the Git Flow methodology and always doing a rebase when wrapping up a feature.

I have high hopes for version 8.3, which promises to make Ignition fully ready for proper version control — really looking forward to seeing how that evolves.

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [November 7, 2025, 1:22pm UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/3 "2025-11-07T13:22:48Z")

</div>

> [@Eduardo\_Alves](#):
>
> Inside each view, there's a `resource.json` file that contains a hash calculated based on `view.json` and `thumbnail.png`. Just opening the view changes this hash, so Git sees it as a modification. You always have to discard those changes to avoid cluttering your version history.

How do you discard those changes?

> [@Eduardo\_Alves](#):
>
> always doing a rebase when wrapping up a feature.

Does this not mess over your merges all the time? Or I guess already way less if you're able to discard the resource files...

---

<div class="post-metadata">

**Author:** ![DSI600](https://avatars.discourse-cdn.com/v4/letter/d/ad7895/32.png) [@DSI600](https://forum.inductiveautomation.com/u/DSI600)\
**Post date:** [November 8, 2025, 2:02pm UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/4 "2025-11-08T14:02:41Z")

</div>

I have been struggling with trying to figure out a good workflow for a systems integrator that has quite a few customers we are supporting. Most of our customers are small manufacturing companies, that don’t have hardware onsite to do GIT control. So, we host their projects in our Docker environment so we can do development work outside of their ‘production’ network.

We need to start tracking Ignition templates and what the younger engineers are doing as we have found easter eggs in most projects.

- We host GITea locally on our development network

- The Dev gateways are in Docker, mapped to Git-tracked folders

- Engineers would use VSCode for GIT + Designer on Windows VMs that tie to the local docker projects.

* * *

**Workflow**

1. `git checkout -b feature/fix-bug`

2. Make changes in Designer

3. `git push` then merge to `main`

4. PowerShell script could pull `main and`zip the project or is it a manual export of resources from Designer.

5. Take`.zip` and import into site

The above workflow is the only way I can see getting the changes to the site after they have been tested locally. Also becomes tricky if there is onsite work and nobody updates our development network the two could get out of sync.

Is there a better way to handle this type of GIT control?

Most of the videos and or Ignition Deployment Guide seem tailored to large companies that would have dev, test, prod servers onsite.

Would be nice to have a community .gitignore file as well!

---

<div class="post-metadata">

**Author:** ![Eduardo\_Alves](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@Eduardo\_Alves](https://forum.inductiveautomation.com/u/Eduardo_Alves)\
**Post date:** [November 12, 2025, 1:47am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/5 "2025-11-12T01:47:48Z")

</div>

> [@louagejasper](#):
>
> How do you discard those changes?

I only stage files when that view has changes. If it does, I stage all files (view.json, thumbnail.png, and resource.Json) and commit together.

> [@louagejasper](#):
>
> Does this not mess over your merges all the time? Or I guess already way less if you're able to discard the resource files...

My understanding is that resource.json uses a hash derived from thumbnail.png and view.json. If two branches compute different hashes and you merge them, the resulting state makes both hashes invalid. To avoid this, I rebase any branch that might conflict with one that’s already merged, so the hash is recalculated automatically when I run the project, before merging.

---

<div class="post-metadata">

**Author:** ![Eduardo\_Alves](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@Eduardo\_Alves](https://forum.inductiveautomation.com/u/Eduardo_Alves)\
**Post date:** [November 12, 2025, 1:59am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/6 "2025-11-12T01:59:22Z")

</div>

> [@DSI600](#):
>
> Is there a better way to handle this type of GIT control?

It’s hard to say what’s strictly right or wrong. We use Git Flow, similar to your workflow but with a dedicated develop branch. Features branch off develop and merge back into it, resolving conflicts there. Then we create a temporary release/\* branch; after tests and any fixes, we merge to main and back into develop, so main always holds the final version. You can use GitHub workflows or GitLab pipelines to automate building release artifacts.

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [November 12, 2025, 8:29am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/7 "2025-11-12T08:29:47Z")

</div>

Thanks for sharing!  
I'm afraid I don't fully understand your last, and most important sentence:

> [@Eduardo\_Alves](#):
>
> To avoid this, I rebase any branch that might conflict with one that’s already merged, so the hash is recalculated automatically when I run the project, before merging.

The way I understand it:

- Let's say I have a feature branch with changes in view 'xyz'. I try to merge it into develop, but I have merge conflicts, because view xyz was modified by another feature branch, which already merged into develop. Instead of going through the merge conflicts, you first rebase develop into your feature branch.

Is that correct?

\*\* While typing it out, it actually makes quite a lot of sense to do that.

---

<div class="post-metadata">

**Author:** ![Eduardo\_Alves](https://avatars.discourse-cdn.com/v4/letter/e/53a042/32.png) [@Eduardo\_Alves](https://forum.inductiveautomation.com/u/Eduardo_Alves)\
**Post date:** [November 13, 2025, 12:13am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/8 "2025-11-13T00:13:48Z")

</div>

> [@louagejasper](#):
>
> Is that correct?

Yes. In this situation I rebase and run ignition again and create a final commit just to “save” corrected hash.

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [November 13, 2025, 7:59am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/9 "2025-11-13T07:59:07Z")

</div>

Got it! That will help me, thanks for clarifying!

---

<div class="post-metadata">

**Author:** ![louagejasper](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/louagejasper/32/86311_2.png) [@louagejasper](https://forum.inductiveautomation.com/u/louagejasper)\
**Post date:** [March 3, 2026, 10:15am UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/10 "2026-03-03T10:15:03Z")

</div>

After implementing this for our customers, I made a guide on Youtube: [https://www.youtube.com/watch?v=svj5-1t8aAk](https://www.youtube.com/watch?v=svj5-1t8aAk)

---

<div class="post-metadata">

**Author:** ![Noah\_Burnette](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/noah_burnette/32/83777_2.png) [@Noah\_Burnette](https://forum.inductiveautomation.com/u/Noah_Burnette)\
**Post date:** [March 3, 2026, 2:46pm UTC](https://forum.inductiveautomation.com/t/anyone-successfully-using-version-control-and-ci-cd-for-automation-in-your-company/108294/11 "2026-03-03T14:46:16Z")

</div>

Just to add my two cents here. We've been using [trunk based development](https://trunkbaseddevelopment.com/) and it has been quite successful. Especially since we have a small team that deploys continuously. Worth checking out as it lets us iterate quickly without the ceremony of git flow. Obviously, a solid pipeline is required.
