How can i test my pipeline on main branch before merging to main

So, I’m doing some changes in the pipeline and pushing it to the PR branch.
I have quite complicated logic and many steps that run on different conditions, specifically on different branches.
Is there an easy way to emulate the pipeline as if it was run on main branch, while in fact it is in a PR branch?

Ideally I’d like to trigger the build manually and be able to set env variable to override the branch name so that Buildkite thought that it runs on main branch.
(Not sure how other people get around it, but it seems to be so basic need for a bit more complicated pipelines)
Addition: I’m using dynamic pipelines of course
Thanks

Hey @MishaLT :waving_hand: welcome to the community!

That’s an interesting use case, I think the easiest way to do this would be to modify the step conditionals on your branch to run on that specific branch. During your testing you can modify the conditionals to match your branch name, and then change them before pushing to main to ensure you’re testing the logic correctly.

Thanks for the reply :slight_smile:
but that’s the whole point - I need to make sure that specific steps run on specific branches.
If i modify the pipeline to run all steps on not main branches, how would this help me?
The goal is not to modify the pipeline but to emulate runs on different branches

Yeah, I understand wanting to be able to emulate the runs on different branches, but if you’re trying to manage that at a step level it’s not going to work, given the purpose of the conditionals is to run those steps conditionally.

One way to approach it might be to set some environment variables (like BUILDKITE_BRANCH) prior to generating your pipeline YAML, and then using buildkite-agent pipeline upload --dry-run to check the uploaded steps, if you want to verify the steps generated match what you’re intending to run in the build for that branch.

If you’re wanting to “test on main”, your best option would probably be to create a separate pipeline, and using the same approach as above where you’re modifying environment variables to then dynamically generate the steps to be run in the “test” pipeline, is probably the way to go.

Could you share the current logic of your pipeline here? I might be able to offer up some other suggestions if I can have a look at your current workflow.

Thanks for the suggestions.
There is nothing really specific int he pipeline itself.
Just a bunch of steps being run for 3 major use cases (on different branches).

Unfortunately, DevEx on developing complex pipelines is not really great already.
And not being able to test it easily is one of those issues.
As I mentioned in the initial message, it would be great to have some env var which you can set manually, something like “BUILDKITE_BRANCH_OWERWRITE” and the pipeline will behave like it is running on this specified branch.
Would be nice if you can consider implementing something like that.
I don’t know if I’m the only person who would ask for this. But to me it looks like a pretty common scenario.
At the moment the only option for me is to make a change, merge to main, test, then create a fix, merge into main and then test, etc…

Hey @MishaLT :waving_hand:

Just for my own clarity; you want to “fake” running a pipeline on main when actually using a feat/ branch (or similar)? You mention “3 major use cases”, just wondering if you’re able to shed any light on what they are?

Honestly, I don’t recall seeing this request in the past; most folks tend to run their tests on non-main and often skip most tests on main due to them already running in an environment designed to accurately represent the environment they’ll be shipped to.

There are some steps you could take, like containing your logic in script files to determine the presence of an environment variable, then use if [ -n ENV_VAR] in the script to run some default logic if that variable has not been set.

I’d suggest maybe emailing us at support@buildkite.com if you’d like to go in to more specific details on your use cases and not on a public forum :slightly_smiling_face:

The only alternative here would be to change the steps of the pipeline from within the YAML editor in the web view.

Let me add a bit more details here:
the repo I’m working on hosts a few npm packages. And some of those packages are code-generated as well.
So we have plenty of different steps: testing and linting of the code files, testing and linting of the code-gen code, then generating those packages and publishing it into NPM under RC or stable versions. plus one flow is actually triggered from Github Actions via Buildkite API.
So obviously I cannot test publishing release version of the package on PR branch.
On pr branch I only can publish RC version. So if I ever made changes to the process of building and publishing stable version, I never can test it, except after merging to main. And then it will actually publish the package to the NPM, even if there was a bug.
So I understand that for some traditional scenarios like developing a web server and then simply building and deploying it to different environments the feature I’m proposing does not seem to be needed.
But in my case the whole DevEx is super bad at the moment :(

Hi @MishaLT, I understand that we’re talking about the experience of testing your Buildkite pipeline config. You have the buildkite.yaml stored in your repo, and you want to test changes to it in a branch before merging that to main. But the config has conditionals based on the Git branch that is being built, so you need a way to test those aspects of the config with arbitrary branches, not just the PR branch where you are mocking up the changes. Do I have that right?

There is one thing that I am not sure about - you said:

On pr branch I only can publish RC version. So if I ever made changes to the process of building and publishing stable version, I never can test it, except after merging to main.

So am I understanding correctly that, for the purposes of your testing, it’s OK to run the ‘main’ or ‘release’ conditional of your pipeline against the code in your testing branch? That doesn’t cause problems for your process, and it will be sufficient to validate the pipeline?

If I’m getting this right, then it’s correct that there isn’t a way to e.g. have Buildkite check out a branch named “pipelinetest” but then run the build with variables as though it has checked out the “main” branch. At least, the build.branch variable is always going to be the actual branch that was checked out, and you can’t override that. I understand how this makes testing your changes pretty annoying. I have two suggestions that might make things a bit easier.

First, you could modify your branch conditionals to check a custom variable, rather than build.branch. This variable would be modified while you are testing the different conditionals; otherwise, it is just a copy of build.branch. This would work best if you used a dedicated branch just for testing the pipeline config, and the config had no conditionals that fire on that branch. For example, let’s say your branch is called “pipelinetest” and your actual development branches are “main,” “feature,” and “experiment.” Then your pipeline code might look like this:

env:
  # TESTBRANCH: build.branch
  TESTBRANCH: "main"

steps:
  - command: echo 'This was a build of the main branch'
    if: build.env("TESTBRANCH") == 'main'
  - command: echo 'This was a build of the staging branch'
    if: build.env("TESTBRANCH") == 'staging'
  - command: echo 'This was a build of the experiment branch'
    if: build.env("TESTBRANCH") == 'experiment'

Now, if you build or commit to your “pipelinetest” branch, a build will run with no steps, so effectively nothing will happen. But if you change the value of TESTBRANCH to “main” and push that commit, it will trigger a build which will exercise the conditionals for “main.” Same for the other two code branches. I’ve tested this out and confirmed that it works. Once you are done testing, you would change your code back to:

env:
  TESTBRANCH: build.branch
...

My second suggestion is along similar lines, but instead of editing the pipeline.yaml in your repo and committing it repeatedly, create a new testing pipeline in Buildkite and paste your YAML into the steps editor in the UI. Don’t use the buildkite-agent pipeline upload step. You can target the same git repo where your code lives. But now you could edit the YAML in the Buildkite UI, change the TESTBRANCH variable as appropriate, and run repeated builds to exercise the different conditionals. This way saves you the work of making repeated commits and pushes to your “pipelinetest” branch during this process. Once you are satisfied that the code works the way you want, you can transplant it into your pipeline.yaml file in the repo.

I realize that this still sounds a bit convoluted, but I think these suggestions help address the problem that you’re describing. Please let us know what you think!

Thanks,
I think this is not the best approach, but definitely better than other options.
Just need to not forget to revert the temporary change before merging it

Hi @MishaLT, I’m glad that was at least somewhat helpful :slight_smile: I’d be interested to hear more of your thoughts about how the user experience around pipeline testing could be better. You mentioned the idea of having some kind of override variable that could be set, but that feels like a kind of narrow solution for one specific issue around testing with different branch variable values. If you have any suggestions for more generalized improvements in this area, please feel free to share them!