Build variable not available in yml template?

According new feature template https://docs.drone.io/template/yaml/, I defined a yml template include build variables

  - name: notice
    image: lizheming/drone-wechat
    settings:
      title: "{%if success %}😊{% else %}😭{% endif %} #{{.build.number}} {{.repo.name}} ${DRONE_DEPLOY_TO}"

with failed error

function "build" not defined

Before I use template, use {{build.number}} works fine, how to translate this into yml template?

The template is evaluated before the build is created, and before the build number is auto-incremented. This means you cannot use {{build.number}} in your template because it is not yet available. You can find a list of available fields at https://docs.drone.io/template/variables/

If build not available in template, there should be a way pass build varibles from .drone.yml to template,otherwise,we will never use build varibles with template or we can use build varibles but never use template, and we can’t use template and multi pipelines together…that seems not design logical

If build not available in template

{{ .build }} variables are supported, however, {{ .build.number }} is not a supported template variable. If you are interested in learning more about how it works you can audit the code here https://github.com/harness/drone/blob/master/plugin/converter/template.go#L96

{{ .repo.name }} also not work?

when I remove build.number variable, got another error

executing "welcome.yaml" at <.repo.name>: can't evaluate field name in type interface {}

Is there misunderstandings using variable in yaml template?

1 Like

Having understood the architecture here, how do you reason about the build number at all in a templated scenario @bradrydzewski? For example, I’ve got steps I’d want to commonize that build containers and charts with the revision number of the build (as it’s operator friendly to have sequential build numbering here that aligns between Drone’s UI and the container tags).

Is there any other way to reason about those values at all in a templated step, such as escaping them so they don’t get processed on the template conversion etc, but instead at execution time, or some other way to smuggle the number into the steps for execution?

There is no template variable for build number since the template is evaluated before the build is created (and therefore before a number is assigned). However, you still have options, including environment variable substitution as described in https://docs.drone.io/pipeline/environment/substitution/

So essentially use ${{DRONE_BUILD_NUMBER}} instead, and even if I reference that in the template we’re all bueno? Is that equally applicable/available to pipeline plugin parameters?

as an example, let’s assume you have the following template:

kind: pipeline
type: docker
name: default

steps:
   - name: build
     image: plugins/docker
     settings:
       repo: {{ .input.repo }}
       tags: ${DRONE_BUILD_NUMBER}

and you have the following .drone.yml in your repository, which uses the template:

kind: template
load: plugin.yaml
data:
  repo: foo/bar

when the template is evaluated at runtime, it would generate the below pipeline configuration, which makes use of environment variable substitution to inject the build number:

kind: pipeline
type: docker
name: default

steps:
   - name: build
     image: plugins/docker
     settings:
       repo: foo/bar
       tags: ${DRONE_BUILD_NUMBER}

also note that substitution uses ${variable} syntax. The example in your previous comment uses double-brackets and would likely result in a template evaluation error.

-${{DRONE_BUILD_NUMBER}}
+${DRONE_BUILD_NUMBER}
1 Like

One last one @bradrydzewski - I’ve tried a few permutations of syntax, but how would I escape:

  • The character # in the template where I’m using it to do things like say “Build #${DRONE_BUILD_NUMBER}” - it seems to choke out on those.

  • When using the plugins/slack - the {#success} and {{since build.start}} expressions.

I’ve tried every way I can think of logically to do $${{"#"}} or equivalent, to try and get these characters past the template phase into the output - but no dice. I’ve split some conditional slack messaging steps apart as a workaround and not using # anywhere in text, but it’d be good to understand what I’m doing wrong/where I’m mis-reading the documents?

Keep in mind that you may also need to escape {{ and }} fields so that they are not evaluated along with the Go template. See the following for further explanation and an example:
https://stackoverflow.com/questions/17641887/how-do-i-escape-and-delimiters-in-go-templates

Below is an example of what might be required. Please keep in mind that this needs testing and you may need to adjust the code further to get it working. But the main takeaway is that the template is executed as a Go template, which means your template syntax needs to follow Go template rules.

-{{since build.start}}
+{{"{{"}}since build.start{{"}}"}}
1 Like