jbrunton / gflows

A CLI tool that makes templating GitHub Workflows easy
MIT License
30 stars 3 forks source link

Question (ytt) - how to add several steps #198

Open kbakk opened 3 years ago

kbakk commented 3 years ago

Hi,

I'm trying to add several steps, e.g

- uses: actions/cache@v2
  id: cache
  with:
    path: |
      **/node_modules
    key: cache-${{ runner.os }}-${{ hashFiles('**/package.json', 'yarn.lock') }}
- name: Install packages
  run: yarn install

I've experimented a bit, and found that I can use:

#@ for/end val in test():
-  #@ val

But I can't get this work, if test() is defined as:

#@ def test():
- name: test 9
  run: echo 9

- name: test 1
  run: echo 1

- name: test 2
  run: echo 2
#@ end

I then get an error:

      error .github/workflows/build.yml (from .gflows/workflows/build)
  ► - cannot load steps.lib.yml: Unmarshaling YAML template 'steps.lib.yml': yaml: line 8: did not find expected <document start>
      error .github/workflows/gflows.yml (from .gflows/workflows/gflows)
  ► - cannot load steps.lib.yml: Unmarshaling YAML template 'steps.lib.yml': yaml: line 8: did not find expected <document start>

This works on the playground:

image

I did find that I could define test() as several documents. It works, but it looks a bit strange:

image

Is this a limitation in ytt, or in gflows?

Anyways, thanks for creating this library! 🙌

jbrunton commented 3 years ago

Hi @kbakk: I'm not a ytt expert, but I believe this error occurs because, in the words of dkalinin in this thread on the Kubernetes Slack:

ytt templates are expected to be valid yaml. because of that its not enough to rely on function "boundaries" (def and end lines) to separate different types of content (in your case an array used inside the function and the rest of the document).

https://get-ytt.io/#example:example-function uses yaml doc separator on lines 31 and 46 to make sure array (line 43) is separated from map (line 47).

I see that your screenshot from your first example in the playground does include a document separator (---). Can you confirm whether your source files for the workflow includes an appropriate document separator too? (EDIT: This is why splitting across several files also works, but it should be possible to combine multiple yaml documents into a single file using separators.)

kbakk commented 3 years ago

Thanks for the links, that did help solve this issue.

So defining

#@ def test():
- name: test 9
  run: echo 9

- name: test 1
  run: echo 1

- name: test 2
  run: echo 2
#@ end

in a separate file does work (sorry, I didn't include that in the description because I didn't consider it would make a difference).

What I was trying was this:

#@ def setup_go():
  uses: actions/setup-go@v2
  with:
    go-version: "^1.14.4"
#@ end

#@ def test_a():
  - name: test 9
    run: echo 9

  - name: test 1
    run: echo 1

  - name: test 2
    run: echo 2
#@ end

Which when put into a YAML linter will throw an error:

Error : Unable to parse.
Line : 1 uses: actions/setup-go@v2

If I add --- to define several documents, it's then valid YAML, and it renders correctly. So this works:

#@ def setup_go():
  uses: actions/setup-go@v2
  with:
    go-version: "^1.14.4"
#@ end

---

#@ def test_a():
  - name: test 9
    run: echo 9

  - name: test 1
    run: echo 1

  - name: test 2
    run: echo 2
#@ end

Let me know if you would like me to create a PR to include such an example in .gflows/workflows/gflows/gflows.yml.

jbrunton commented 3 years ago

@kbakk: Glad it worked, and thanks for the offer of a PR! This is a pretty common gotcha when using ytt, but I'm just pausing to think about where the best place to add references might be. I don't want to clutter the default workflow too much, but a link to documentation elsewhere (and some example workflows) would definitely be useful. I'll have a think.