Avoid including all workitems on first build on new branch - azure-devops

Our CI/CD is currently set up so we continually produce installers when PR's are completed. However that is for our internal pipeline. When we are ready to release, we open up a stabilization branch (release branch) where we do various things, like flicking a switch in the binaries so they no longer present them as being internal test binaries, but regular production binaries.
The problem is then in the WorkItem tracking. The first build on the release branch shows up as including every workitem included since day 0, and even adds the build to the work items. But we are only interested in marking work items that are in PR's targeting the new release branch, rather than the entire history up till the point of branch creation.
Here's an overview of how we branched out. "4.9.6" only contains one PR (2 commits and 1 merge commit), and the master branch continued ahead:
This is then the first CI build triggered on the release branch:
For some reason it seems to have just included the latest 50 commits (I believe it just capped out there), which also results in a long list of "Linked work items". However, there was only 1 work item included in the only PR in the lifetime of the "4.9.6" branch.
Is it possible somehow to avoid that, or even just a way to work around the issue?

Related

Azure ADO branching and release strategy to only include delta since last build to show as associated WorkItems with a build

My question is a continuation to this post:
Close work items automatically on Release to specific environment
This accepted answer will work perfectly, but only if I can make sure that a build shows just the delta since last build as associated WorkItems, instead of all work items from history. Sometimes I see all items in history as associated work items in a build.
Builds are happening for several environments (Dev, QA, UAT, Prod). How do I make sure that when I run a new build, it only has delta since the last build in that same environment so that I am only looking at new changes that are coming in with a new build?
Update:
I think I get what you mean. Please see if my understanding is accurate: your master branch has many PRs and links to many workitems. You create release1 from the master, and then when the branch is run based on release1 for the first time, the API lists the associated workitems of all the commits of the master. The second time, the incremental workitem compared to the first time can be displayed normally. Later, you created release2 from the master. When the branch was run based on release2 for the first time, the API listed the associated workitems of all commits of the master(This is not you want.). The second time, the incremental workitem compared to the first time can be displayed normally. . What you want is to display incremental workitems from the last run of the branch based on release1 the first time the branch is run based on release2?
If so, it's obviously not possible to use this API to achieve the requirements. As I said in the answer, this API fetch increment refers to the increment based on the same branch, it does not apply to different branches.
But you still have a way to get the "increment" you want, check out this API:
https://learn.microsoft.com/en-us/rest/api/azure/devops/build/builds/get-work-items-between-builds?view=azure-devops-rest-6.0
You just need to compare.
Original Answer:
but only if I can make sure that a build shows just the delta since
last build as associated WorkItems, instead of all work items from
history. Sometimes I see all items in history as associated work items
in a build.
Why do you say 'make sure'?
The API should only get the delta workitems(under the same branch).
I think changes should not contain all of the work items linked to all of the previous commits(since it is only 'changes').
Do you mean the behavior on your side is unstable, do you mean sometimes contains delta changes but sometimes contains all of the changes during the branch lifecycle?
If not, then the understood of yours maybe a little false.
If yes, I think you need to report this issue to the Developer Community. Please also provide your problematic build url there in this situation. StackOverflow is an open forum, so it's not suitable for handling stuff with private information.
Builds are happening for several environments (Dev, QA, UAT, Prod).
How do I make sure that when I run a new build, it only has delta
since the last build in that same environment so that I am only
looking at new changes that are coming in with a new build?
I suggest you put each environment in a different branch, then when you run pipeline based on the related branch, the pipeline should only get the delta changes of current branch and the API should only get the delta workitem commits since the last pipeline run of current branch.

How to handle release candidates in git-flow

We're working by the git-flow workflow. Typically we release some release candidates (RC, v1.0.0-rc.0) before we ship the final release (v1.0.0).
To do so, we have a release branch (release/1.0.0). The release candidates are just tags within that branch. The release branch is not merged into main until we have a final release.
Today we discussed whether we should open a release branch for every release candidate (e.g. `release/1.0.0-rc.0) and merge these into main whenever the candidate is released.
Any opinions on this one?
Generally, if each of the previous release candidates are reachable by the newest one, then they could be on the same branch, and therefore there isn't any benefit to having separate branches for each.
If you wish to make a new release candidate that does not start from the current release candidate (e.g. perhaps you need to back up a few commits, or even start over), then that would be a good time to consider creating a new branch.
I assume once you merge into main you can delete all of the release branches, whether they were fully merged into main or not. Since you still have the old release versions tagged that you didn't use, you could always go back to them if you wish, even without the branches.

Strange merge behavior in Azure DevOps using Git

The business recently planned to test two separate features in the same sprint, but weren't sure if both of them were going to be deployed. Our solution was to create two feature branches off of Develop, one for each feature, and a third branch off of develop ("the Hybrid Branch") into which those feature branches could be merged. We would only deploy to DEV and QA from the Hybrid Branch, allowing dev and QA to test both features. If one of them was pulled back, the individual feature branch would be merged to develop and deployed without the other.
But we've encountered some strange behavior with one of the feature branches when merging into the hybrid branch.
When creating a pull request, Azure DevOps merges every change from the date that the feature branch was created. It's as if the branch doesn't get rebased properly after a push or merge or what-have-you.
For the other feature branch, it pulls only the set of commits pushed since the last merge. This is how we expect it to work.
This makes reviews of the pull request difficult, as it's difficult to isolate the specific changes for the PR. It also means that resolved conflicts have to be re-resolved for every PR, and the PR acts like previously added or removed files need to be added or removed again.
What could be causing this and how do we resolve it?
I think it's because of squashing. The way git works isn't by tracking a "last merged commit pointer". Every time you merge branches, git looks for any commits that are present on one branch and not present on another. It does it by comparing hashes. So if you merge with squash, then those commits are merged to another branch with different hashes, so the next merge will show them as new commits again.
Regarding one branch working properly, maybe the other branch was rebased to the first? You can check hashes of commits to make sure that they are indeed different on both branches

Is publishing a package to npm necessary when a file that is ignored by npm is changed and published to GitHub?

The project contains a test folder that is ignored by npm but is not ignored by GitHub. When a change occurs in a file under the test folder, should it be also published to npm in order to keep versions matching? Also, in that case, semantic versioning should be increased while there is no change for npm.
Assume that there is a repo in GitHub which has a test folder that is ignored by npm. It also has the package.json file which is tracking version number inside the repo.
Q1. When a change occurred in a file under the test folder, should the patch version number be increased?
Q2. Somehow (if the answer of Q1 is yes, as it is in the first question but there might be other similar cases), when a minor version increase happened in the package.json file, but nothing is changed in the files on npm side, what should be done?
Last edit first:
The short answer to your question is no. The repo will march on ahead of whatever is published in your feeds until you cut a new release.
So the problem here is that you apparently track version numbers either in a file in your repo, or in the commit labels/tags. Don't do that, it's pointless. I know it's a very common practice (I've made that mistake myself), but it is born out of lazy thinking. Repo's are not the right kind of database to track this sort of thing. Only published packages need to have any kind of version label on them. The data-flow should be from repo => build system => package repository. The arrows should never be reversed.
When you apply that rule, your question is moot. Your test content is a separate package feed from your release content (NPM). It already has repo hashes, that are unique, unambiguous and immutable. Those hashes should flow to the build system, then to the package feed/repository system.
There is always a difference in the release date/time stamps between test and product development. Product releases always lag test releases. The purpose of a particular version of the test suite, is to validate a product release. So you should always see test suite X.Y.Z+repoHashN, precede product version X.Y.Z+repoHashN. Note that the values of X, Y and Z for test and product, need not have the same values (a product patch, might be the result of fixing known bug surfaced by the test suite), but there should always be a 'repoHashN' that uniquely matches a test version triple and product version triple.
You produce two products, an app and a test suite, from the same repo, and most of the tooling out there tracks a version per branch that is applied to all packages produced from that branch. I can't directly address any specific NPM behavioral issues, I don't use it enough, but I am fairly sure you are not encountering a bug, rather you are most likely using it incorrectly.
Because your two products develop on separate cadences, you should consider maintaining a test branch for versioning test code. There's a seemingly endless variety of possibilities for your workflows here.
I recommend using a master or main branch for the tip of all development. Always cut prerelease (-<#>+master.<repoHash>) versions from this branch, and you might as well only ever bump either the patch number or the prerelease tag number (NPM supports either scenario). Then, when you are ready to cut a release, you fork master or main into a release branch (named after the target major.minor version) and cut only release packages out of that branch. Because your test code version is not relevant to the release package version, you don't need to track that specifically, it's always updated when you merge from main/master or test/dev branches to cut the next patch level release. The patch level of the release branch only gets bumped when you are ready to release it to the public.
Do test development in a test branch to hide the churn that doesn't need to show up in the master/main history. A dozen "BUG:### WIP" entries aren't needed there so you squash merge from test to master or main. Same thing holds for product code development. Do that in a Dev branch. Test and dev branches should only ever cut packages with something like a -<#>+<devNam>.<repoHash> tag on them and only published to private feeds.
The purpose of master/main branch is to provide frequent (at least daily) build and test cycles that include merged content from test and dev branches. This is where you maintain ground truth. At any given time you should be able to safely fork a new branch from here and count on it to build a product that meets your quality specs. This allows you the freedom to cut release branches at whatever cadence you need, independent of the current state of the test or dev branches. Test and dev, should attempt to merge their work into master or main, at least daily, and immediately fix any merge conflicts or build failures.
In the case where test == dev, you can combine them into a single branch. Generally, each developer will have many branches in progress, for independent work on various tasks. Having them merge directly to main or master is a valid workflow and even considered a best practice in many shops. Sometimes, too many cooks in the kitchen however, can cause problems, and when you find your dev's are spending too much time resolving merge conflicts with master or main. You'll want separate branches for different lines of effort, for them to stage their work into, before taking it to master. Then flow into master or main isn't quite so random, and will be easier to manage.

Gerrit: working with multiple branches & propagating changes

I'm trying to identify the proper way of working with multiple branches on Gerrit that would match our workflow.
The way we work with branches right now is: we have master & feature branch. Master is the branch we want to polish and make it ready for release, while feature is obviously a field of intensive work. Now, in our particular case whenever somebody works on a bug fix, they:
create a change targeted for master branch
cherry pick it to the feature branch targeted change
once gerrit code review completes, submit both changes.
now the way i understand cherry-pick, it selects individual commit and merges it to the current change. if that is the case, i would expect to have no merge conflicts in the end, and indeed this workflow works perfectly with just GIT. Gerrit, however, most likely due to its nature (branches are not merged remotely the way these are locally and get a different sha tag) lists a tremendous number of conflicting files in the end.
Now, I resolved all these issues by applying merge strategy (ours on feature, theirs on master), but it does not feel right: if anything was not propagated, it just got discarded.
My question is: is there a safe workflow, similar to the above one, that would in the end produce a clean merge with gerrit?
I would say that it's better, in this case, to merge than to cherry pick.
A cherry pick adds the same changes but not the same commit. So while the source is the same on a cherry pick and merge the git tree is different. When the tree is different and you later do a merge git will think that the commit you previously cherry picked is missing and try to merge that change as well, even if the actual code is already there. That's probably why you get a lot of conflicts.
I would propose another way of working.
When you do normal work you develop on feature and push to Gerrit as normal.
When you do a patch (ie bug fix) on the stable production environment you do that directly on master (or local branches if you like but not on feature)
When the patch as been approved in Gerrit it get's merged into the real master and you can make a pull request to get that change to your local copy. Your version of master is now the same as Gerrits master
Now you would merge all new changes on master into feature. Make sure you do a rebase so that the patch ends up before anything you've already done on feature
Once it's time to deploy all new features you can merge feature into master, push to Gerrit (if you have permissions you can by pass gerrit by pushing directly to master instead of refs/for/master as these changes are already reviewed)
Once all changes are on Gerrits master you do a pull on your master and a merge into feature with rebase making feature a clean branch to work on. It's of course totally valid to have a new feature each release. Both work fine.
I'm a little confused, as this flow should work just fine. If other users submit changes before your bug fix is reviewed/verified/submitted, that could result in merge conflicts, but that should be rare.
If you:
Fix a bug on master
Push to review (creating change A in gerrit)
cherry-pick change A on top of the feature branch (resolving any conflicts from master to feature)
Push the cherry-picked change to review (creating change B)
Review/verify/submit changes A & B
Everything will work fine. The only way for merge conflicts to occur is if other users upload and submit changes between steps 1 and 5. Are you seeing different behavior? Can you provide more details?