.gitpod.yml and making sure init: completes before command:

We’re looking at moving our team to GitPod, and I’m working with projects of increasing complexity.

I’ve got some Sphinx-based documentation projects working, and the team are pleased with the results. Now I’m trying a Rails app.

What I would like to have happen is bundle install runs, and then the various tasks run in their own windows.

I’m stuck and I think read everything and also most of the examples I can find.

This is what I have so far, which works except the command: lines start up before the init: has completed, so they mostly fail as Rails isn’t installed yet.

tasks:
  - init: >
      bundle install &&
      yarn install --check-files &&
      rails db:setup 
  - name: Rails
    command: rails server
  - name: Webpack
    command: bin/webpack-dev-server
  - name: Redis
    command: redis-server
  - name: Sidekiq
    command: sidekiq

My questions:

  • How can I ensure init completes before anything else?
  • I’ve seen > and | used in this file. What do those characters do and what’s the best practice?
  • I’ve also seen commands concatenated with && and sometimes not. I’m not sure I understand why and think it might be something to do with > and |?

Many thanks for any help. We’re really enthused with GitPod so far, just a few little tweaks…

Simon

Hi @simoncoles, welcome to the Gitpod community! :tada:

Super cool! :100:

Indeed. The problem here is that every “-” symbol under “tasks:” configures a seperate Terminal, and all Terminals run in parallel.

The order beforeinitcommand is only guaranteed for within a single Terminal, e.g.:

tasks:

  - before: echo "this always runs first"
    init: echo "this runs next, but will be skipped in subsequent restarts of this workspace"
    command: echo "this always runs last"

  - command: echo "this will 'race' the Terminal above"

So, in order to ensure an init runs before a command, you can add them both to the same Terminal.


However, if you’d still like to run multiple Terminals that each rely on some common init to finish, you can make use of gp sync-await <name> and gp sync-done <name>, e.g. like so:

tasks:

  - name: Rails
    init: >
      bundle install &&
      yarn install --check-files &&
      rails db:setup &&
      gp sync-done bundle # 'bundle' is an arbitrary name I picked
    command: rails server

  - name: Webpack
    init: gp sync-await bundle # wait for the above 'init' to finish
    command: bin/webpack-dev-server

  - name: Redis
    init: gp sync-await bundle
    command: redis-server

  - name: Sidekiq
    init: gp sync-await bundle
    command: sidekiq

This way, every Terminal’s command will wait for the lock I called “bundle”, which only gets released when all the necessary init steps are complete.


Indeed, this is a YAML thing that’s a bit confusing.

From what I understand, both > and | are used to specify multi-line commands, except > will just fold every line into a single line (like text), while | builds an array of multiple commands that will be run one after the other (so no && needed).

I believe the following examples are equivalent:

tasks:
  - init: bundle install && yarn install --check-files && rails db:setup
tasks:
  - init: >
      bundle install &&
      yarn install --check-files &&
      rails db:setup
tasks:
  - init: |
      bundle install
      yarn install --check-files
      rails db:setup

The only exception that comes to mind is with |, where I’m not 100% sure that an error in one line will prevent others from running (e.g. if yarn install --check-files fails, maybe rails db:setup will still be executed in the | example).

This uncertainty is why I personally only use single-line or > multi-line.

2 Likes

Thank you that’s exactly what I needed to know. You’ve made my week :slight_smile:

2 Likes