Best practice for building multiple branch triggers with multiple tags

Let’s suppose I am building docker containers with multiple triggers, i.e.

  • development -> ...:latest
  • release/* -> ...:latest + ...:latest-release
  • master & version tags, e.g. v1.0.0 -> ...:latest + ...:1.0.0 + ...:1.0 + ...:1

For master & version tags, obviously, auto_tag: true is the best fit. Currently, for master, release/*, and development I have created separate pipelines:

---
kind: pipeline
type: docker
name: foo-version-master
...
    settings:
      ...
      auto_tag: true

trigger:
  ref:
    - refs/heads/master
    - refs/tags/v*

---
kind: pipeline
type: docker
name: foo-release
...
    settings:
      ...
      tags:
         - latest
         - latest-release

trigger:
  ref:
    - refs/heads/release/*

---
kind: pipeline
type: docker
name: foo-development
...
    settings:
      ...
      tags:
         - latest

trigger:
  ref:
    - refs/heads/development

Although, of course, this works like intended it is a lot of “boilerplate” code. drone.yml becomes quite long with a lot of code duplication.

What would be the best practice to achieve this behavior?

Ideally, I would think of either chaining config files, like only defining the pipeline names and triggers in drone.yml and and the actual steps: inside foo.yml (since they are exactly the same for each build, they just differ in triggers and corresponding tags).

Or, alternatively, something in the direction of mapping triggers and tags to use:

trigger:
  ref_and_tag:
    refs/heads/development:
      - latest
    refs/heads/release/*:
      - latest
      - latest-release
    refs/heads/master:
      - auto_tag
    refs/tags/v*:
      - auto_tag

This functionality would be super handy and significantly reduce the lines of code in drone.yml while, at the same time, drastically improving readability.

instead of separate pipelines with duplicate steps, you could have a single pipeline and use the when clause to limit step execution. You could further explore yaml anchors, extensions and aliases to reduce boilerplate.

kind: pipeline
type: docker
name: default

steps:
- name: build
  image: golang
  commands:
  - go build

- name: test
  image: golang
  commands:
  - go test

- name: publish
  image: plugins/docker
  settings:
    repo: foo
    auto_tag: true
  when:
    ref:
      - refs/heads/master
      - refs/tags/v*

- name: publish
  image: plugins/docker
  settings:
    repo: foo
    tags: latest
  when:
    ref:
      - refs/heads/development

- name: publish
  image: plugins/docker
  settings:
    repo: foo
    tags: [ latest, latest-release ]
  when:
    ref:
      - refs/heads/release/*

- name: notify
  image: plugins/slack

Alternatively, if you have multiple pipelines defined in the same yaml and want to reduce boilerplate, the recommended approach is to use jsonnet. See How to reduce Yaml boilerplate

@bradrydzewski thanks for the fast reply!

So I tried to define some extensions, but drone directly fails at line 1 with unknown anchor 'envssh' referenced:

x-envssh: &envssh
  environment:
    SSH_PRIVATE_KEY:
      from_secret: SSH_PRIVATE_KEY

...

---
kind: pipeline
type: docker
name: build

steps:
  - name: base
    image: plugins/docker
    <<: *envssh

Would you have any hint on this issue? Google did not help this time :confused:

when you define anchors they need to be in the same document (in your above example, they are in separate yaml documents, separated by the ---). This is a limitation of the yaml specification, not Drone itself.

@bradrydzewski Yes, also just noticed that keeping the definitions inside one pipeline, so “below” the ---, resolves the issue. Thank you very much!