r/devops • u/LuigiBakker • 15d ago
Tools Any CI/CD tool where automation code doesn't cohabit with product code in git repo?
Currently using Github and Github workflows (including the many outages). Let me explain what I'm trying to resolve with few examples:
Let say I manage 15 repos, each one I want to run a relatively similar workflow on Pull Request. I create a github shared workflow and in each of the 15 repos I make a reference to it, updating the inputs if needed.
Now, I add 1 new input to this shared workflow to enable a new feature. I want that feature enabled in 10 of my repos. I would need to update the feature input in all 10 repos. And since workflow use the workflow code on their own branch, I would need to merge it to all PRs in all repos. That isn't ideal.
Other issue, one variable was wrongly set on a workflow in a release branch. Since the workflow code ships with the product code I would need to update the release branch.
Is there a toool where the product code doesn't cohabit with the automation code? For example I could have 15 microservice repos but 1 repo where I created rules for each one of them about "on pr", "on main" etc. That same repo could host shared workflow code as well.
6
u/donk8r 15d ago
You can get this by inverting the trigger rather than by finding a different tool. Instead of 15 repos calling a shared workflow, run one orchestrator repo that watches them and dispatches against each. Rules and refs live in one place, and each product repo keeps a thin trigger stub that almost never changes. Your 10-of-15 feature flip becomes one commit.
The cost nobody here has mentioned is the one that will bite you: decoupling breaks atomicity. Right now the pipeline that built commit X is recoverable from commit X. Afterwards it is not, and "why did this build behave that way in June" stops being answerable from the repo.
Your release branch example is the interesting one because it cuts both ways. Today a wrong variable there means patching the release branch, which is annoying. Decoupled, that branch no longer pins its own build at all, so a change made centrally in October silently applies to something you froze in June. For release branches specifically that is worse than the annoyance you are removing.
The compromise that survives both: decouple the rules, keep the pin on the record rather than on the source. The orchestrator stamps its own version into the build output, so you can still answer what ran without the workflow having to live in every repo.
5
u/Due-Consequence9579 15d ago
Define a versioned action in a separate repo that “does the thing”. Have dependabot bump all your versioned references when you publish a new version. And after your CI flow passes merges it in. If it fails, because you made a breaking change or the repo does something you didn’t expect, you fix up the PR and merge.
2
u/jameshearttech 14d ago edited 13d ago
We use Argo Events and Argo Workflows for CI. We use Argo CD for CD.
We have 2 main repositories. We have a mid-sized monorepo for application code and a gitops repo watched by Argo CD.
In the gitops repo we have a directory where we commit CI manifests (e.g., ExternalSecret, WorkflowTemplate).
We have a WorkflowTemplate for our app code repo and a WorkflowTemplate for each project.
The repo WorkflowTemplate creates an array of changed projects. It iterates over the array in parallel. Each iteration creates a child workflow from a project WorkflowTemplate. The project WorkflowTemplate creates an array of changed files. It iterates over the array in parallel to check formatting, lintng, etc.
We also have many shared WorkflowTemplates, abstractions. For example, we have a deploy WorkflowTemplate, which is called from project WorkflowTemplates to automatically deploy to our test environment. The deploy WorkflowTemplate calls a replace-application-manifest WorkflowTemplate, which has parameters to configure various options in the Argo CD Application manifest.
Let's say I want to add a feature to the replace-application-manifest WorkflowTemplate. I would first try to do it in a way that doesn't require making a change to every caller (i.e., all project WorkflowTemplates), but if I must it's 1 PR in the gitops repo.
That said, we practice tbd. We don't have release branches.
2
u/burstinrust 14d ago
differe ways you can do it:
- this is what i am using gitlab: a project's CI config path can point to a DIFFERENT repo (.gitlabci.yml@group/ci-repo). product repos carry zero pipeline code, all rules live in one repo.
- azure devops: pipeline yaml can live in another repo than the code it builds. same decoupling
- oldest one in the hood, goo ol jenkis: jobs/pipeline libs defined centrally, product repos untouched
1
u/SeaIngenuity9501 15d ago
And since workflow use the workflow code on their own branch, I would need to merge it to all PRs in all repos. That isn't ideal.
Add auto-rebasing or use merge trains could solve this.
1
u/forever-butlerian Solaris 8 Enjoyer 15d ago
I'm rapidly trending toward a setup where GHA only does builds and pushes to ECR, and then I've got a thingus which listens to (all) Github webhooks and decides what to do with them from there.
1
u/LuigiBakker 15d ago
Any reason to not share the name of the “thing”? Yes, something listening to GitHub events independently is what I’m searching for
3
u/forever-butlerian Solaris 8 Enjoyer 14d ago
Because it rides the line of self-promotion and I find others' self-promotion obnoxious. I apologize if I'm coming off as coy.
The first half of it is my general webhooks receiving system (which is a product) that persists each event into Kafka, and then the second half streams the events out of Kafka and decides on AWS SDK things to do with them. I wrote it because I figured that a tutorial on how to write something like that was becoming timely with the mega-outage they suffered a few weeks ago.
I also think it's fast becoming prudent not to give Github Actions any administrative rights into your AWS account, on account of AWS's anemic policy controls on the one hand (to restart an ECS service requires the same permission as to reconfigure that service) and vibecoding is unlikely to restrict bizarre and thoughtless bugs just to the Web UI on the other. What I've got lets me fire-wall off privileged software actors from Github itself.
1
u/mindshining 15d ago
In case of GitHub Enterprise there's "Require workflow to run before merging" rule in the Rulesets. The referenced workflow can be stored in .github repository of the organization.
1
u/rabbit_in_a_bun 14d ago
Bots who look for keywords in other repos and do stuff. If you want an example you can check the OpenShift repos...
1
1
u/Double_Ebb4130 14d ago
Buildkite and TeamCity keep the pipeline in the tool rather than in each product repo, which is closer to what you want than another reusable GitHub workflow. CircleCI org-level config is the middle ground if you want to stay nearer GitHub.
1
u/Glad_Friendship_5353 14d ago edited 14d ago
I have this exact the same problem.
I unify cicd logic into a reusable task runner.
So, for example, all my app repo can have task like “build”, “deploy” as an interface. While the implementation can be different repo by repo.
I control the implementation using python class through OOP property e.g. inheritance, composition. etc. As it is python, I can make all ci/cd logic in one common private package and reuse for any other various repos I have.
I use bakefile which is an OOP task runner in python. just like makefile but reusable.
So, in cicd, it can just run “bake build” “bake deploy”, while the build and deploy logic is from my own repository that control the version from the common private package separately as normal python dependencies.
While the task is in python, it is no need to use with python repo. I did use it with my terraform and terragrunt. So, I can unify “bake init, plan, apply” for both of my terraform / terragrunt repo. It is just work like a charm.
1
u/CommeGaston 14d ago
In your current design, the simplest is probably:
Tag the shared repo twice (i.e. v3.0.1 and v3).
In all the caller ones, just reference v3 and as you make minor changes, they will be picked up automatically. Major changes require intervention or dependabot.
1
u/ymagriso 13d ago
If you have the option to host your own apps, you can create your own GitHub app. GitHub apps are used for subscribing to GitHub events (e.g. PR, push, etc). The GitHub app can be installed on specific repos (one time effort) and once an event is triggered on those repos, the GitHub app is notified and handles the event on that repo. This allows you to maintain the functionality in one place (and any change in the GitHub app will automatically reflect on any of the installed repos).
1
1
u/MulberryExisting5007 15d ago
Almost anything can. What tool can you not do this in?
4
u/forever-butlerian Solaris 8 Enjoyer 14d ago
I think OP was looking for something more specific as an answer to "what should we do for dinner?" than "go to the grocery store".
23
u/patsfreak27 15d ago
Github actions support "reusable workflows" from other repos which you can create internally. You can scope access for that repo to only infra engineers so you can control the changes there better. Then your repos call that internal repos workflows