Hi. Is there any way to inject .drone.yml once the repository is cloned? I wouldn’t like to have a .drone.yml per repository in my organization, but a centralized repo with all yamls defining project-specific pipelines. The reason for this is basically that we wouldn’t like to expose all the build steps and some specifics to people that have access to those repos (yeap, we can’t remove 'em — they should have access to the code, but not to the build pipeline).
What I thought in doing so far is creating a plugin that basically clones another repo, copy the specific .drone.yml for the project and replace with the current one that invokes the plugin. I’d still have an “empty” yml file in the project that would invoke this plugin, but not really sure that would work. I mean, it’s fine to have, but it’s kinda crappy 'cause ideally we wouldn’t reveal any of that.
What I thought in doing so far is creating a plugin that basically clones another repo, copy the specific .drone.yml for the project and replace with the current one that invokes the plugin.
This would not work because drone fetches the Yaml configuration file using the API before the repository is cloned. The Yaml is then compiled and all the build steps are pre-calculated. It would therefore not be possible to hot-swap a Yaml configuration on the fly.
I am not aware of any workarounds that would enable a central repository of shared Yaml files.
Hey @bradrydzewski. I made it — it’s working! Thanks for the tip, however, I had to do HTTPS_PROXY and do some more “manual” stuff. Really simple setup, wrote a server in Go and coded some interceptions to change couple of behaviors as I needed.
drone 1.0 has a dedicated endpoint that you can use to override how the yaml is fetched, which can be used to inject / override / modify the yaml. It is configured by passing the following environment variables to the server.
The secret (above) is a shared secret that you provide to the server and the plugin, used to secure communications between the two.
We provide a starter project for creating yaml plugins, as well as an example plugin that is capable of processing a jsonnet file and returns a valid yaml back to drone:
I have one question though, is it possible that I render a different YAML based on whether it’s running a BUILD vs a DEPLOYMENT?
I’ve got a number of use cases for that …say for example that when I build my repository it generates a Docker image that when we confirm the deployment we’ll push it to the registry.
Hey @bradrydzewski I am trying to return a dynamic YAML pipeline file using the env DRONE_YAML_ENDPOINT as you mentioned.
Everything is looking fine in the process, but when the Drone hits my API that should return the YAML content, it shows the following error:
{"commit":"c4a8c2aaec7489db8515341110d0faa25f0fa7b0","error":"invalid character 'k' looking for beginning of value","event":"push","level":"warning","msg":"trigger: cannot find yaml","ref":"refs/heads/drone-test","repo":"Govlaunch/ui","time":"2019-02-18T02:13:09Z"}
I am trying returning a static yml content just for testing purposes by setting the header “Content-Type: text/yaml”
@bradrydzewski I would like to create a yaml file on the fly based on the repo by checking the files in the repo. if it has package.json add a npm build or if it has pom. add a maven build. How can I read the files using the plugin extension?
@vivekthangathurai you would have to create your own plugin extension [1][2] that reads files from github and then returns a yaml. To read files from github you can use the github API [3][4].
EDIT here is some pseudo code that shows how this could work, based on this sample extension.
// creates a github client used to fetch the yaml.
trans := oauth2.NewClient(ctx, oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: p.token},
))
client := github.NewClient(trans)
// get the configuration file from the github
// repository for the build ref.
data, _, _, err := client.Repositories.GetContents(req.Repo.Namespace, req.Repo.Name, path, &github.RepositoryContentGetOptions{Ref: req.Build.After})
if err == nil && data != nil {
// get the file contents.
content, err := data.GetContent()
if err != nil {
return nil, err
}
return &drone.Config{
Data: content,
}, nil
}
// if the configuration file does not exist, and a package.json
// file exists return a default node pipeline
data, _, _, err = client.Repositories.GetContents(req.Repo.Namespace, req.Repo.Name, "package.json", &github.RepositoryContentGetOptions{Ref: req.Build.After})
if err == nil {
return &drone.Config{
Data: "..... your node yaml here ....",
}, nil
}
// if the configuration file does not exist, and a pom.xml
// file exists return a default maven pipeline
data, _, _, err = client.Repositories.GetContents(req.Repo.Namespace, req.Repo.Name, "pom.xml", &github.RepositoryContentGetOptions{Ref: req.Build.After})
if err == nil {
return &drone.Config{
Data: "..... your maven yaml here ....",
}, nil
}
return nil, nil