-
Notifications
You must be signed in to change notification settings - Fork 2.8k
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
Report files changed to limit testing scope #1021
Comments
The same idea in another perspective, based on directories that have been changed, vs file extension. |
I think there two interesting use cases here, from what I can tell:
I think perhaps we need to step back and fully discuss the problems we are trying to solve. The solution (described in this issue) may very well be the correct solution. But it would help to fully document the different problems / use cases we are trying to solve before we settle on the solution(s). |
As it might help someone in the mean time, this is what I use as a workaround right now: |
I guess I can toss in two example problems that we have:
This can already be worked around, but it'd be good to either document how to do so or to figure something better out. I don't have strong preferences for either approach. |
So do we need the ability to limit steps by files or folders changed? Or load different yamls based on files or folders changes? Or both?
I get the sense that each sub-project in a mono-repo might want to manage its own yaml file and possibly its own secrets, but I'm not entirely sure. |
For our usage case, I'd be pretty happy limiting steps by file/folders changed. We could load different yamls based on changes, but that could get to be a confusing situation pretty quickly as far as variable/secret surface area. |
What @mrueg works for build steps, but would not for plugins since they don't execute bash. If conditions can be plugin-fied, that would really enable whatever condition you want to compare on (filename extensions, changeset directory, regex on git tag names, obtaining a lock, making a request out to some external api, etc... In addition to the conditions that already exist today). As long as the plugin returns 0 to continue, or 1/anything else for skip. |
Written up my thoughts and ideas on handling monorepos. Proposal for how Drone could handle monoreposSummaryBy a monorepo I mean a single repository that contains multiple projects. So at the very least for a monorepo you would want to some how filter what ApproachesKeep current .drone.yml but provide a changeset filter for pipeline stepsAs suggested in #1021 (comment) Pros
Cons
Allow for multiple .drone.ymls per repoIn this case Drone needs to know where the the sub .drone.yml files are. Root .drone.yml contains location of sub configs (MY PREFERENCE)Store the metadata for sub .drone.ymls in a root .drone.yml (perhaps with a different name e.g. .drone.root.yml) Data per sub yml
Pros
Cons
Store sub yml metadata on drone serverData per sub yml
Pros
Cons
Implicit scoping of sub yml files to their children directoriesAll .drone.yml files in a repo are picked up and builds will be run for them. Pros
Cons
Scan for and read all sub yml files on each commitAs above but without the implicit scoping Pros
Cons
|
Good ideas @jamesk; I like the explicit subdir-yml file line of thinking as this forces people to be aware and maintain yml files, keeping them tidy, and being very declarative for Drone. Implicit reading of yml files can become confusing and becomes hidden/documentation knowledge.
|
@tonglil Yeah I prefer the sub yml approach as well. In Response:
In the usual case I think you would want the working dir to be where the sub yml is. Perhaps though an extra parameter can be added to the
I was thinking that each "pipeline" i.e. sub yml would get its own build history in Drone, probably by adding an extra field to the unique key for builds i.e. I thought it would be good to behave like the branch filtering, not even creating a build if the commit is not relevant. Github for instance has no way of deleting commit statuses, so if you first made a build I think you'd have to create X pending build statuses where X is number of projects in the monorepo, then later mark them each as successful (even though you ended up not running anything in them). For this reason I was thinking along the lines that the main Drone server should be able to easily and quickly make any decisions around whether to trigger a build like it does for branch filtering i.e. based purely on the contents of yaml config and info about the commit. My understanding is that if it was left to a plugin we would need to spin up the plugin docker image, which would usually only be done on the drone agents as part of a build? |
Perhaps instead of sub-yaml we define sub-projects in Drone? It is conceptually similar, but perhaps more general purpose and might support more use cases. For example:
So basically instead of Every repository would have a default project, with the ability to create additional projects. So the visual / user experience would not change for single-project repositories (you would see just the default). The complexity of multiple projects would only be exposed to those that need it. |
This sounds potentially confusing to explain to the users. Repeating ourselves in .drone.yml isn't sexy, but I'd almost prefer verbosity and explicitness there rather than starting down this more complicated path. At least at this stage in Drone's development (pre-1.0). |
This is definitely more of a 2.0 change. I think there is some precedence here now that gitlab supports subgroups which is conceptually similar: Reference request to support subgroups in drone #2009 I share the concerns about the UX but think this is something that could be overcome. The UI hides the fact that technically every build is a matrix build, for example. But I agree that we should limit the initial implementation to changeset analysis in the when clause. It provides an immediate (albeit more verbose) solution, which we can always build upon. And it prevents us from making a more complex change that cannot be undone once implemented ... I think we can perhaps split these into a 1.0 proposal and then a 2.0 design document that evolves over time as we observe the 1.0 behavior. I see this being similar to the golang proposal process which is definitely more long term focused https://github.com/golang/proposal/tree/master/design |
I think a 2.0 change is totally fair. The verbosity and explicitness is becoming an issue with larger projects/repositories, where it becomes very cumbersome to parse though a |
I think you're overcomplicating it. the git plugin just needs to do the same thing as concourses git-resource, which is emit a truthy when new commits contain specified globs. if a repo has many different projects, then sure.. specify their own drone.yml... but that's really a different topic. (installing a directory subset from a repo as a drone project) |
Perhaps the two systems are architected a bit differently. In drone, the yaml file is fetched using the GitHub API and then pre-compiled to an IR and executed. This happens before any code is cloned and creates a bit of a chicken and egg issue. Under different design constraints a more simple approach like this would work. |
@bradrydzewski it's the same in concourse, you install the pipeline before any code is cloned. concourse does this via cli client. But the point I'm making is that here in this ticket, it has turned from "we need the pipeline to continue or not based on the presence of files in the commit" to "lets change how a project is setup". that second topic... it's a whole other feature request. |
also, in concourse I can have as many or as little pipeline.yml files all over my repo, but some tasks in a pipeline are always going to need file glob based conditionals regardless. |
The current version of Drone does not have guaranteed access to the file system of a running build. It is possible for Drone to launch builds on a remote machine using the Docker remote API or the Kubernetes API. This is a design constraint that needs to be taken into consideration.
I think the goal is to understand the different use cases and developer workflows that we need to support. This issue (not criticizing the op) proposes a solution, however, we cannot be sure it is the best or optimal solution until we gather such information. For example, one solution to the ops issue (slow tests) could be parallelism and a solution to mono-repositories could be multiple yaml files; neither of which require diffs or file globs. Or we could come to the conclusion the ops original proposal is the preferred solution. So far I think this thread is generating some good discussion.
This is also a possibility. There is certainly a benefit to a fresh pair of eyes taking a fresh approach. Have you considered creating a patch to demonstrate how this could be solved in a more simple way? |
Also since we are gathering use cases and information, it would be great if you could prove more context. What underlying problems or use cases are you hoping to solve with globs? |
I'm in the midst of working on a pair of repos that could benefit from steps that are conditionally ran on changes to certain file patterns. Here's what it looks like for both repos:
As such, it'd be great if we could only build one of the 5 sub-dirs if they get touched. It is true that there are other ways around this, in breaking the larger repo up into more numerous repos. However, the team in question already has established workflows and has quite a few non-pure-engineer contributors that value the simplicity. It can be significantly more difficult (given their backgrounds and skillsets) to manage six separate repos with their own build/deploy flows instead of one. If I was able to do something like:
We'd be pretty stoked and would have an easy way for our teams that use more bulky repos to proceed. |
I've tried to nail it this way:
Not yet working as i'd like, sometimes if i delete folder/a.file and add folder/b.file git returns R100 instead of A and D. That stuff is strange. But it was fast try, gonna rtfm git again. |
BTW got exactly same problem, team uses monorepo, one folder is And i also have a repo with a bunch (100+) ansible roles, which i'd like to be able to test on docker/vm's, one change triggering them all would be a kill. |
@bradrydzewski The use case is that you have a repo whose parts thereof are not built as one thing, different parts of the repo may be built in different ways. Lets look at a typical repo I deal with at Fusion: $ ls -al ./
./repo/
client/
src/
styles/
main.scss
server/
something.sln
ccnet.build
foo.ps1
yarn-cache/
Dockerfile
docker-compose--build.yml
docker-compose--build.yml.tmpl
docker-compose.yml
docker-compose.yml.tmpl
package.json
.eslintrc
.yarnrc There are three major things going on here:
All three of these job pipelines should only be triggered when the respective files change. So for example we don't want a cruise control build running when none of the files under Luckily, cruise control has directives around file exclusion triggers. We've solved that. At the moment, I'm using concourse where resource changes (or manual ui button click) triggers pipeline runs. In our pipeline, I describe the various parts of the repo as resource-types:
- name: git-branches
type: docker-image
source:
repository: vito/git-branch-heads-resource
tag: latest
resources:
- name: frontend-source
type: git-branches
source:
uri: "{{project_repo_uri}}"
private_key: {{bitbucket_ci_private_key}}
branch: develop
paths:
- client/**/*
- package.json
- yarn.lock
- .yarnrc
- name: docker-image-source
type: git-branches
source:
uri: "{{project_repo_uri}}"
private_key: {{bitbucket_ci_private_key}}
branches:
- master
paths:
- docker/**/*
- yarn-cache/**/*
- package.json
- yarn.lock
- .yarnrc Above you can see, two resources All concourse git resources get new commits, but they only emit changes and trigger on when the commit contains paths that match the globs described. further on in the pipeline I wire that up like so : jobs:
- name: build-image
public: true
serial: true
plan:
- do:
- get: docker-source
trigger: true
params: {depth: 1}
- task: get version
config:
platform: linux
image_resource:
type: docker-image
source: {repository: realguess/jq}
inputs:
- name: docker-source
outputs:
- name: version
run:
path: sh
args:
- -exc
- |
jq '.version' --raw-output < ./docker-source/package.json > version/tag
echo "Sniffing Version $(cat version/tag)"
- put: image-builder
params:
build: docker-source
dockerfile: docker-source/docker/Dockerfile
tag: version/tag
tag_as_latest: true
This job pipeline only runs when the Now the important part is my pipeline file is called Now the reason I'm here annoying you is that concourse is awesome... like seriously awesome stuff, but you really have to be a lover of the command line to get anything done with it. It doesn't have the nice UI that drone has. I started making a ui for this... but at some point I want to have a life and the rest of the team here at Fusion isn't going to understand how to manipulate the command line to get new projects into concourse. I'm trying to decide if Drone is the tool that will save me from writing the custom UI for concourse. without path filters though... it doesn't seem likely. Drone is really nice, the UI is great, so even if you implement a feature where installing a project lets you detect nested |
Hello, Been reading the comments here and the proposals sound very interesting. I take it there is no workaround to run the existing plugins referenced by @foosinn and @microadam with a BitBucket repository right now, right ? 😞 |
@bogdan-calapod Yes. only support |
I got that, I was just wondering if there is any way to do per-folder / per-file-changed jobs with a BitBucket repository |
@bogdan-calapod you would have to fork one of the plugins mentioned above and then adapt to use bitbucket instead of github. Bitbucket exposes a diffstat endpoint to a list of changes for a commit. |
Cool - will try to fork it then. Thanks! |
Did anyone ever get any success getting one of these plugins working with bitbucket? |
@natewarr bitsbeats/drone-tree-config#2 added support for bitbucket |
So? Which one is the best solution? I hope this feature can be supported officially, not by plugins. |
It's not planned in the near future to add it to the core, so far it is based on plugins and AFAIK is bitsbeats/drone-tree-config working pretty well. |
@w4-hanggi there are multiple plugins with at least 4 distinct approaches to solving this problem (and I am told a team is about to release a 5th approach). I am not sure there is a best solution yet. Each approach I have seen is unique and is optimized for different repository structures. The reason we delegate this problem to plugins is because a) we do not use monorepos and therefore lack experience and perspective required to design an effective solution and b) because it gives the broader community an opportunity to experiment with different solutions, gather feedback and see if a preferred solution emerges. We hope a preferred solution emerges and that we can integrate into core, however, I expect this to take many months, if not longer. We are still seeing new, creative approaches to this problem being published and we need to give the community time to evaluate. |
I agree with this approach. Monorepos are clearly becoming very popular with the advent of gitops and container based micro services. Saying that... It's very early days, as much as we all want this to drop, its just not ready. There are so many tools and approaches in the monorepo ecosystem I don't see it settling for a long time. |
I don't think it's solely related to monorepos though. I just don't want to rebuild every time my readme changes. :) |
Fair use case. Never thought down that line, I believe most folk have dedicated CI infrastructure? So running a build just uses what’s sitting there. (Sorry if this is getting conversational) |
(Adding yet another solution to the solution pile) I solved this with the "exit config" exit code (78), which skips subsequent steps. It works like:
That + Skylark support allows me to get ... most of the way there. This additionally illustrates the use case -- a repo full of Dockerfiles. |
True but this can also help with build avoidance (the repo has many submodules and you don't want to run the whole 1 hour+ test suite and just run tests for things that changed) |
I found this workaround:
More about 78 exit code here: |
Ok guys, just stumbled over this issue... I would love to specify a condition when certain files/directories change. The recent workaround from @ezhukov somehow doesn't work for me, looks like the DRONE_COMMIT_BEFORE env var is empty (private bitbucket on premise, maybe https://discourse.drone.io/t/drone-commit-before-is-always-empty-on-bitbucket/4998). Any more ideas to get this working? |
Drone supports this by config extensions which are already out there. |
@tboerger do you have a link to documentation or config extension? |
There are already multiple extensions out there, further information about |
I am going to lock this because some of the previous comments are getting buried, leaving people with the impression that no solutions exist. To recap: This is currently handled by extensions: Anyone can create an extensions using our starter projects Extensions can be used to override how Drone fetches a yaml allowing you to create or modify yaml files on the fly. There are multiple extensions that solve this problem today that you can use. Here are a few:
Here are previous comments that explain why this is being delegated to extensions and why we have not (yet) added this feature natively to Drone.
|
Currently we have a long running test suite for a product. This gets enough commits that running the full suite would back up the build server. To limit that it would be nice to get back what files are changed.
As a contrived example usage assume that we have 3 sections to the app, A, B, and C, and each of these has a corresponding test suite. If any files within A's space change then just the A test suite needs to run.
This will allow for quicker turn around time for any functional/integration tests.
The text was updated successfully, but these errors were encountered: