Code Monkey home page Code Monkey logo

drone-tree-config's Introduction

Drone Tree Config

This is a Drone extension to support mono repositories with multiple .drone.yml.

The extension checks each changed file and looks for a .drone.yml in the directory of the file or any parent directory. Drone will either use the first .drone.yml that matches or optionally run all of them in a multi-machine build.

There is an official Docker image: https://hub.docker.com/r/bitsbeats/drone-tree-config

Limitations

Currently supports

  • Github
  • Gitlab
  • Bitbucket #4

Usage

Environment variables

  • PLUGIN_CONCAT: Concats all found configs to a multi-machine build. Defaults to false.
  • PLUGIN_FALLBACK: Rebuild all .drone.yml if no changes where made. Defaults to false.
  • PLUGIN_ALWAYS_RUN_ALL: Always rebuild all .drone.yml. Useful when repository has a global dependency, like executing tests on all projects in repo before building individual artefacts. Defaults to false.
  • PLUGIN_MAXDEPTH: Max depth to search for .drone.yml, only active in fallback and always fallback modes or when pipeline was triggered by cron. Defaults to 2 (would still find /a/b/.drone.yml).
  • PLUGIN_DEBUG: Set this to true to enable debug messages.
  • PLUGIN_ADDRESS: Listen address for the plugins webserver. Defaults to :3000.
  • PLUGIN_SECRET: Shared secret with drone. You can generate the token using openssl rand -hex 16.
  • PLUGIN_ALLOW_LIST_FILE: (Optional) Path to regex pattern file. Matches the repo slug(s) against a list of regex patterns. Defaults to "", match everything.
  • PLUGIN_CACHE_TTL: (Optional) Cache entry time to live value. When defined and greater than 0s, enables in memory caching for request/response pairs.
  • PLUGIN_CONSIDER_FILE: (Optional) Consider file name. Only consider the .drone.yml files listed in this file. When defined, all enabled repos must contain a consider file.
  • PLUGIN_FINALIZE: Adds dependencies to all other pipelines to a user provider pipelined named finalize.

Backend specific options

  • SERVER: Custom SCM server (also used by Gitlab / Bitbucket)
  • GitHub:
    • GITHUB_TOKEN: Github personal access token. Only needs repo rights. See here.
  • GitLab:
    • GITLAB_TOKEN: Gitlab personal access token. Only needs read_repository rights. See here
  • Bitbucket
    • BITBUCKET_AUTH_SERVER: Custom auth server (uses SERVER if empty)
    • BITBUCKET_CLIENT: Credentials for Bitbucket access
    • BITBUCKET_SECRET: Credentials for Bitbucket access

If PLUGIN_CONCAT is not set, the first found .drone.yml will be used.

Example docker-compose

version: '2'
services:
  drone-server:
    image: drone/drone
    ports:
      - 8000:80
    volumes:
      - /var/lib/drone:/data
      - /var/run/docker.sock:/var/run/docker.sock
    links:
      - drone-tree-config
    restart: always
    environment:
      - DRONE_OPEN=true
      - DRONE_SERVER_PROTO=https
      - DRONE_SERVER_HOST=***
      - DRONE_GITHUB=true
      - DRONE_GITHUB_SERVER=https://github.com
      - DRONE_GITHUB_CLIENT_ID=***
      - DRONE_GITHUB_CLIENT_SECRET=***
      - DRONE_GIT_ALWAYS_AUTH=true
      - DRONE_SECRET=***
      - DRONE_RUNNER_CAPACITY=2

      - DRONE_YAML_ENDPOINT=http://drone-tree-config:3000
      - DRONE_YAML_SECRET=<SECRET>

  drone-tree-config:
    image: bitsbeats/drone-tree-config
    environment:
      - PLUGIN_DEBUG=true
      - PLUGIN_CONCAT=true
      - PLUGIN_FALLBACK=true
      - PLUGIN_SECRET=<SECRET>
      - GITHUB_TOKEN=<GITHUB_TOKEN>
    restart: always

Edit the Secrets (***), <SECRET> and <GITHUB_TOKEN> to your needs. <SECRET> is used between Drone and drone-tree-config.

Enable repos via regex matching

By default, this plugin matches against ALL repo slugs. If you want to enable the plugin for specific repos only, turn on regex matching by specifying a PLUGIN_ALLOW_LIST_FILE.

  • Regex match rules must comply with re2 syntax.
  • Each line is a single rule.
  • Empty lines are ignored.
  • Lines which start with # are treated as comments (ignored).

Updated docker-compose:

  drone-tree-config:
    image: bitsbeats/drone-tree-config
    environment:
      - PLUGIN_DEBUG=true
      - PLUGIN_CONCAT=true
      - PLUGIN_FALLBACK=true
      - PLUGIN_SECRET=<SECRET>
      - GITHUB_TOKEN=<GITHUB_TOKEN>
      - PLUGIN_ALLOW_LIST_FILE=/drone-tree-config-matchfile
    restart: always
    volumes:
      - /var/lib/drone/drone-tree-config-matchfile:/drone-tree-config-matchfile

File: drone-tree-config-matchfile:

^bitbeats/.*$
^myorg/myrepo$
  • Matches against all repos in the bitbeats org
  • Matches against myorg/myrepo

Consider file

If a PLUGIN_CONSIDER_FILE is defined, drone-tree-config will first read the content of the target file and will only consider the .drone.yml files specified, when matching.

Depending on the size and the complexity of the repository, using a "consider file" can significantly reduce the number of API calls made to the provider (github, bitbucket, other). The reduction in API calls reduces the risk of being rate limited and can result in less processing time for drone-tree-config.

Given the config;

   - PLUGIN_CONSIDER_FILE=.drone-consider

A local git repo clone;

$ tree -a my-repo-clone/
 my-repo-clone/
 ├── .drone-consier
 ├── foo
 │   └── .drone.yml
 ├── bar
 │   └── .drone.yml
 └── baz

Content of the .drone-consider to check in;

$ cat my-repo-clone/.drone-consider
foo/.drone.yml
bar/.drone.yml

The downside of a "consider file" is that it has to be kept in sync. As a suggestion, to help with this, a step can be added to each .drone.yml which verifies the "consider file" is in sync with the actual content of the repo. For example, this can be accomplished by comparing the output of find ./ -name .drone.yml with the content of the "consider file".

Caching

If a PLUGIN_CACHE_TTL is defined, drone-tree-config will leverage an in memory cache to match the inbound requests against ones that exist in the cache. When a match is found, the cached response is returned. Cached entries are expired and removed when their per-entry TTL is reached.

Example (expire after 30 minutes);

 - PLUGIN_CACHE_TTL=30m

Depending on the size and the complexity of the repository, using a cache can significantly reduce the number of API calls made to the provider (github, bitbucket, other). The reduction in API calls reduces the risk of being rate limited and can result in less processing time for drone-tree-config.

drone-tree-config's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

drone-tree-config's Issues

Rate limit hit

What's the purpose of checking .drone.yml (or some other file) from every folder?
Can't it be just checked based on file listing from the API?

We are getting rate limit errors with monorepos since it tries to get Drone config file from every sub folder there is.

Gitlab support?

I need to apply drone to a monorepo in gitlab. I'm willing to fork this repo, however, I'm newbie to go. Would you mind giving me some info or hint to help me kick off?

Git tags / Release support

Hey man, after a long day of fighting with drone to figure out why tags don't work with an 404 not found error - i discovered that there is a problem getting events related to tags with this plugin.

In scm.go you can see that when event comes with a ref of refs/tags/ it goes to the else which in this case is comparing the branch with 00000000 then it fails because it tries to go to google-go-github function of branch listfiles.

I searched google-go-github for a tag related event handling but did not find any... instead there is only a get asset of a release which includes all the code...

is there a way of telling the plugin that whenever the ref is refs/tags/ it should go back to how drone natively discovers the changes or you thing it is possible to implement this in scm.go with this module https://github.com/google/go-github/blob/e4b511744f5bbb020d00e172a284468137d4e5fc/github/repos_releases.go

i can help by PR changes but i need a direction

Documentation: Timeouts of consideration

It should be noted (in the documentation?) that the following timeouts can impact the functionality of this extension. If you have a deeply nested source tree and/or large repository, you could encounter these.

  1. Github expects a webhook response in 10 seconds. Drone calls this extension synchronously while processing the /hook request. If this extension takes longer than 10 seconds to respond, Github will close the connection which will trigger Drone to cancel the request context. This will result in no pipeline for the change.

  2. Drone gives all config extensions 1 minute to respond. If you are not subject to a timeout by the Drone /hook caller (e.g. not GitHub) and if this extension takes longer than 1 minute to respond, Drone will cancel the request context resulting in a Post: {drone-tree-config address} context deadline exceeded message in the Drone server logs. This will result in no pipeline for the change.

These considerations are applicable only for whitelisted repo slugs, when the primary functions of this extension occur.

did not find a .drone.yml

Hello

I try you plugin for setup drone, because I have multi module projects, and as far as I know, this plugin is the only way so solve this. Currently I try to setup drone for my backend, frontend will be the next step.
So I added .drone-consider with

$ cat .drone-consider
backend/.drone.yml

And a .drone.yml in backend/: https://github.com/mavarazo/archivit/blob/feature/next/backend/.drone.yml

While checking the container it logs the following error:

time="2021-01-20T21:19:42Z" level=info msg="server listening on address :3000"
time="2021-01-20T21:20:57Z" level=info msg="e73f8e77-8531-4a1a-a49a-437115d4c4a3 mavarazo/archivit started"
time="2021-01-20T21:20:57Z" level=info msg="e73f8e77-8531-4a1a-a49a-437115d4c4a3 match: mavarazo/archivit"
time="2021-01-20T21:20:57Z" level=debug msg="e73f8e77-8531-4a1a-a49a-437115d4c4a3 checking mavarazo/archivit .drone-consider"
time="2021-01-20T21:20:57Z" level=debug msg="Repositories.CompareCommits 200: https://api.github.com/repos/mavarazo/archivit/contents/.drone-consider?ref=adbebee6d116fa37e2720029a241002eaaf9adca"
time="2021-01-20T21:20:57Z" level=debug msg="drone-tree-config environment" after=adbebee6d116fa37e2720029a241002eaaf9adca before=1f3f6af1a9733ac35a4e261becdab192765566bf branch=master ref=refs/heads/feature/next slug=mavarazo/archivit trigger=@hook
time="2021-01-20T21:20:57Z" level=debug msg="Repositories.CompareCommits 200: https://api.github.com/repos/mavarazo/archivit/compare/1f3f6af1a9733ac35a4e261becdab192765566bf...adbebee6d116fa37e2720029a241002eaaf9adca"
time="2021-01-20T21:20:57Z" level=debug msg="e73f8e77-8531-4a1a-a49a-437115d4c4a3 changed files: \n  .drone-consider"
time="2021-01-20T21:20:57Z" level=info msg="e73f8e77-8531-4a1a-a49a-437115d4c4a3 finished"
time="2021-01-20T21:20:57Z" level=debug msg="config: cannot find configuration: mavarazo/archivit: feature/next: did not find a .drone.yml"

The plugin omit "..." in commands in steps

I found an issue that my drone that install this plugin cannot run the command go test ./.... After build got trigger, it will convert go test command into go test ./.

This is the example of test case:

kind: pipeline
type: kubernetes
name: default

steps:
- name: vendor
  image: golang:1.14-alpine3.11
  environment:
    CGO_ENABLED: 0
    GO_PRIVATE: "<repo.com>/*"
  commands:
  - apk add --no-cache git
  - go mod vendor

- name: test
  image: golang:1.14-alpine3.11
  environment:
    CGO_ENABLED: 0
  commands:
  - go test ./...

The result of my ci is :

Screen Shot 2563-05-21 at 09 57 59

Failed SCM connections should be handled properly

plugin.NewScmClient should return an error if something goes wrong. Currently, it returns nil client that causes panic later on.

Here is a log:

time="2019-12-12T08:25:46Z" level=info msg="c1343e95-2072-41f4-a477-5f6f035ca14e _EDITED_"


time="2019-12-12T08:25:46Z" level=error msg="**Unable to connect to SCM server**."


time="2019-12-12T08:25:46Z" level=info msg="c1343e95-2072-41f4-a477-5f6f035ca14e match: _EDITED_"


time="2019-12-12T08:25:46Z" level=info msg="c1343e95-2072-41f4-a477-5f6f035ca14e finished"


2019/12/12 08:25:46 **http: panic serving 192.168.80.12:40516: runtime error: invalid memory address or nil pointer dereference**


goroutine 6 [running]:


net/http.(*conn).serve.func1(0xc000075400)


	/usr/local/go/src/net/http/server.go:1767 +0x139


panic(0x96fbc0, 0xe251f0)


	/usr/local/go/src/runtime/panic.go:679 +0x1b2


github.com/bitsbeats/drone-tree-config/plugin.(*Plugin).getScmChanges(0xc0000c8230, 0xadf2c0, 0xc0000fa400, 0xc00010d920, 0xc00011a7b0, 0x26, 0x1, 0xc0000f7b30, 0xb)


	/go/src/github.com/bitsbeats/drone-tree-config/plugin/scm.go:58 +0x313


github.com/bitsbeats/drone-tree-config/plugin.(*Plugin).Find(0xc0000c8230, 0xadf2c0, 0xc0000fa400, 0xc000118840, 0x0, 0x0, 0x0)


	/go/src/github.com/bitsbeats/drone-tree-config/plugin/plugin.go:75 +0x424


github.com/drone/drone-go/plugin/config.(*handler).ServeHTTP(0xc00005f350, 0xade4c0, 0xc0001240e0, 0xc0000ca300)


	/go/pkg/mod/github.com/drone/[email protected]/plugin/config/handler.go:84 +0x21b


net/http.(*ServeMux).ServeHTTP(0xe32be0, 0xade4c0, 0xc0001240e0, 0xc0000ca300)


	/usr/local/go/src/net/http/server.go:2387 +0x1bd


net/http.serverHandler.ServeHTTP(0xc0000d6000, 0xade4c0, 0xc0001240e0, 0xc0000ca300)


	/usr/local/go/src/net/http/server.go:2802 +0xa4


net/http.(*conn).serve(0xc000075400, 0xadf2c0, 0xc00005a500)


	/usr/local/go/src/net/http/server.go:1890 +0x875


created by net/http.(*Server).Serve


	/usr/local/go/src/net/http/server.go:2927 +0x38e

Drone rebuilds everything every time

monorepo structure

project_a/.drone.yml
project_b/.drone.yml
project_c/.drone.yml

Problem

changing/adding/removing a file from project_a (or b/c) always triggers a full rebuild for all 3 projects.

Expected

changing project_a should only rebuild project_a, not all 3.

Configuration

github, aws ec2, aws ecr.

the docker-compose contains:

drone:1.8
drone-runner-docker:1.3
registry-plugin:1.0.0
drone-tree-config:0.3.7

PLUGIN_CONCAT: false
PLUGIN_FALLBACK: false

Also note, the 3 projects are built successfully.

Is this an expected behaviour or am I just missing something?
Thxs.

How to use it on k8s

I am using drone on k8s with kube-runner.

Do you have any tutorial using drone-tree-config on k8s?

Thank you

Wait the end of all pipelines?

We have a monorepo and want to move our CI to drone. We tried your plugin and it works really well.

We just have one remaining issue: we would like to have a pipeline to start our end-to-end test when all our pipelines have successfully finished.

But, because we now have a separate drone.yaml for each project in the monorepository, we don't know how to wait that all pipelines have finished (because we don't know to which pipelines this last one should depend)

Have you already encounter this need? Do you have an idea of how we can achieve this?

Add support for root folder files changing - trigger multiple pipelines

Hey, so far this plugin supports a simple logic - editing files within a folder runs the folder drone file.

But what if for example you have a python monorepo with a shared requirements.txt located in the repo root folder, and when it changes - you need all / multiple pipelines to run.

I know its an advanced feature to ask, i'm willing to help - just need your opinion @foosinn of how you think we can implement this, I think it's very useful feature for everyone.

Multiple commits

Hey guys, your plugin worked great for me until one of our programmers did the following use case:

  • changed folder A, then git commit
  • changed folder B, then git commit
  • changed folder C, then git commit
  • git push to branch - Drone built only folder C

The plugin suppose to go over all commits or only the last one?

v0.3.4 fails to trigger builds on master branch in monorepo

I love this plugin! Everything was running great on ECS with two service definitions:

drone-ci

  • drone/drone:1.6.2
  • bitsbeats/drone-tree-config:latest

drone-runner

  • drone/drone-runner-docker:latest
  • xxx.dkr.ecr.us-east-1.amazonaws.com/drone-vault:latest
  • xxx.dkr.ecr.us-east-1.amazonaws.com/drone-ecr-registry-plugin:latest

Yesterday all of my github webhooks on my master branch were failing to trigger builds. The logs only show a failed response of did not find drone.yml. All other branches were building fine.

Today, I specified the previous version bitsbeats/drone-tree-config:0.3.3 and everything is working again.

I would like to be able to troubleshoot this locally and see what's exactly going wrong.

Jsonnet support

Are you open to this plugin being extended to support Jsonnet? With multiple .drone.yaml files in a repo it's likely you're using something like Jsonnet to reduce redundant build config. So built in support would save on some pre-commit processing.

Gitea support?

Any chance to have this working with a Gitea self-hosted frontend?

Docker images for ARM

Can you also release Armv7 and Arm64v8 images of this plugin in the docker repository?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.