Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support per branch builds and previous build comparison #117

Closed
dbason opened this issue Mar 25, 2020 · 12 comments
Closed

Support per branch builds and previous build comparison #117

dbason opened this issue Mar 25, 2020 · 12 comments

Comments

@dbason
Copy link

dbason commented Mar 25, 2020

Hi,

First off I would just like to say thanks for this project, we've found it really useful. We currently have a fork that we are using for our specific use case, and are wondering if you would accept a PR to support this. Our use case is as follows:

We currently use Jenkins, Artifactory, and Spinnaker to support a CI/CD work flow. Every time the code changes (even if it is reverting previous change) we want to produce a new artifact that we can then pass through our CD pipelines. The versioning uses semver with the short commit hash as metadata. To support this we have introduced a config option in to baur to just look at the last build when comparing the digests.

We also use the CI pipeline to build and deploy pull requests, and we would like these to be tracked separately to the mainline build. This means that we trigger a build when the PR gets merged to master as the digests are tracked separately

@fho
Copy link
Collaborator

fho commented Mar 25, 2020

Hello @dbason,

cool, thank you for the feedback. It's great to hear that baur is also useful for you. :-)

Could you elaborate on why you want to rebuild an application and rerun it through CI if the code did not change?
The main reason for us to use baur is to exactly to prevent that. To prevent rebuilding and retesting an application if there is a past build for the same sourcecode, independent of the branch.

To support this we have introduced a config option in to baur to just look at the last build when comparing the digests.

How do you find the last build in the branch? Do you also store the branch in the database with the past builds?

@dbason
Copy link
Author

dbason commented Mar 25, 2020

Could you elaborate on why you want to rebuild an application and rerun it through CI if the code did not change?

Sure, the simplest answer is that it's a tradeoff we have accepted for simplicity. Our deployment process is triggered by a successful build so fundamentally we want to trigger that process whenever the code has changed from the previous deploy.

Our major use of baur is to calculate which components need to be built in a mono repo. From there we actually pass off Jenkins to do the builds as we have a number of pipeline steps with integrations for things like static code analysis and security scanning, so unfortunately baur doesn't have access to the full build metadata.

We also stamp the code with a semver that includes the git commit hash at build time, this is for auditing purposes, so we do want to produce a new build with the correct commit hash on it. Also because we only keep a limited number of builds in artifactory we can't guarantee that the old build artifact will still be available.

How do you find the last build in the branch? Do you also store the branch in the database with the past builds?

Yeah we have two optional command line flags, one for the branch to store the build against and compare against, and one to compare against if there are no previous builds for a branch. We store the branch as an additional column in the database. The column is filled in with a default if you choose not to use that functionality so it won't affect the existing use.

The initial changes we have made were against 0.16.0. I'm just working through the refactor from 0.17.x now so once I've done that you can take a look at the code changes if you like.

@fho
Copy link
Collaborator

fho commented Mar 27, 2020

@dbason ok, thanks for the explanation and the PR.
I'll discuss it internally and then get come to you, probably next week.

@fho
Copy link
Collaborator

fho commented Apr 3, 2020

@dbason

We welcome your contribution and discussed it internally and were not entirely sure if we understand the motivation behind the proposal correctly.

The following is a summary of my understanding of how you are using baur.
Please check if it's correct and otherwise let me know what is wrong: :-)

In you git repository for each application an .app.toml file with declared build inputs exist.
On a git push you are running baur ls apps --branch <branch> --compare <base-branch>.
The list of applications with a Pending build-status are passed to a Jenkins CI Job.
The Jenkins job runs checks, tests and builds each application.
The Jenkins job does not use baur to build the application.
Therefore you do not have records in the baur database about past builds from the same branch.

So you are using baur to compare changes between branches on application level to figure out what changed via (baur ls apps) but not using baur build in CI.
Is this correct?

thanks and have a nice weekend!

Update: To be able to compare the build status with the base branch. You have to do a baur build on the base branch somewhen. My summary does not add up.

@dbason
Copy link
Author

dbason commented Apr 3, 2020

So we do use baur build, but the build command just touches a file. From there the jenkins job checks the existence of those files and if they exist kicks off the build pipeline for that app.
So it's something like this:

  • On push we have a parent jenkins pipeline that runs baur build
  • Depending on which empty files are create child pipelines are started to build the various apps.

When a pull request is opened we want to build the apps that the pull request has changed. We stamp these with a test version and they get deployed out to a test environment.

When the pull request gets merged to master we want to build anything that has changed from the last build against master branch, and these get stamped with an rc version and deployed out to a CI environment, and then out to production environments.

I hope that clarifies things

@fho
Copy link
Collaborator

fho commented Apr 8, 2020

Yes, I think we got it now. Thanks!

We would like to propose another idea for a feature that should solve your
problem. The proposed feature is generalized, it is not focused on git-branches and
should also fit other usecases.

  1. We add the possibility to specify arbitrary values for baur build that
    are hashed as additional build-inputs of apps.
    Let's call the parameter --additional-input-str for now.
    (We need to come up with better parameter names later.)
    It replaces baur build --branch from your PR.
  2. We add a parameter to specify a list of arbitrary fallback values that are
    hashed as additional build-inputs when querying for existing builds.
    I will call it --lookup-additional-input-str-fallback for now. It accepts
    a value in the format VAL[,VAL]...
    When no build is found with the first VAL as additional build-input in
    the list, baur searches for a build with the second VAL as additional
    build-input in the list and so on.
    It is similar to baur build --compare from your PR.

To rebuild all apps that changed in master after a merge you could run:

baur build --additional-input-str=master

To rebuild all apps in a branch that changed compared to master you could run:

baur build --additional-input-str=feature-x --lookup-additional-input-str-fallback=master

We could also support setting the parameters via environment variables.

@dbason What do you think about the idea? Would it work for you usecase?

@dbason
Copy link
Author

dbason commented Apr 8, 2020

Yeah I think that's a good idea, and it should fit our use case. Would you be happy to keep the option in the app configuration to only compare against the last build?

@fho
Copy link
Collaborator

fho commented Apr 9, 2020

@dbason cool :-)

I think it does not align well with the main goal of baur to avoid unnecessary rebuilds.
The usecase for the option is not clear for me yet. In which cases is it desirable to always only compare the status with the last build?

@fho
Copy link
Collaborator

fho commented Apr 14, 2020

@dbason

We could add a command to diff the inputs of an application, then it is simple to script the functionality to rebuild if the last build differs easily, like:

baur diff inputs --quiet --app MsPaint HEAD HEAD^ || baur build --force MsPaint

The UseLastBuild attribute is not stored with the app in the .app.toml file though.

@dbason
Copy link
Author

dbason commented Apr 14, 2020

Sure that would also work for us. That;s basically what the attribute is doing any way.

The primary use case for this is for if some code has been reverted. We want to build it to trigger the deployment process, and we can't pull the information about the previously build artifacts (and we can't guarantee they still exist).

@dbason
Copy link
Author

dbason commented Apr 14, 2020

@fho would you like me to modify my PR to reflect these changes?

@fho
Copy link
Collaborator

fho commented Apr 16, 2020

@dbason I created 2 issues for the discussed changes:

I'll close this issue and you PR for now.

It would be great if you can help with the implementation and create PRs for those. We should do the implementation in separate PRs per issue against the master branch.

As you noted the baur version in the master branch is different then the last release. Builds are replaced with more generic Task definitions, the database schema will be very different.
It will still take some time to finish it until a version with these changes can be released.
Nonetheless it would be best to do the changes against the master branch.

thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.

2 participants