Custom stage disables default stage matrix expansion

I made a simple Perl project. The initial .travis.yml looked like this:

language: perl
perl:
  - "5.28"
  - "5.26"
env: PGVERSION=system
script: perl -E 'say $ENV{PGVERSION}'

This resulted in two jobs, Perl 5.28 PGVERSION=system and Perl 5.26 PGVERSION=system, as expected.

Then I added a matrix.include to build with perl 5.28 with additional versions of Postgres, like so:

language: perl
perl:
- "5.28"
- "5.26"
env: PGVERSION=system
script: perl -E 'say $ENV{PGVERSION}'
matrix:
include:
    - env: PGVERSION=11
    - env: PGVERSION=10

This resulted in the expected four jobs:

  1. Perl 5.28 PGVERSION=system
  2. Perl 5.26 PGVERSION=system
  3. Perl 5.28 PGVERSION=11
  4. Perl 5.28 PGVERSION=10

Then I added a jobs.include section, like this:

language: perl
perl:
  - "5.28"
  - "5.26"
env: PGVERSION=system
script: perl -E 'say $ENV{PGVERSION}'
matrix:
  include:
    - env: PGVERSION=11
    - env: PGVERSION=10
jobs:
  include:
    stage: Special
    script: perl -E 'say $ENV{PGVERSION}'

I had expected this to simply add a new stage, and it does do that, but it also causes the two jobs added by matrix.jobs to disappear! There are now only three jobs:

  1. Perl 5.28 PGVERSION=system
  2. Perl 5.26 PGVERSION=system
  3. Perl 5.28 PGVERSION=system

What I thought I’d end up with is five jobs:

  1. Perl 5.28 PGVERSION=system
  2. Perl 5.26 PGVERSION=system
  3. Perl 5.28 PGVERSION=11
  4. Perl 5.28 PGVERSION=10
  5. Perl 5.28 PGVERSION=system

Is it expected that adding jobs.include stages would cause matrix.include in the default stage to be ignored?

The first issue you raise (that the jobs in matrix.include only have perl: "5.28") is explained here https://docs.travis-ci.com/user/customizing-the-build/#explicitly-included-jobs-inherit-the-first-value-in-the-array.

The second is a little more subtle: jobs is an alias for matrix when we process the configuration. In YAML, the last one always wins, so matrix is completely hidden by the subsequent jobs.

Oh, that’s unexpected. Would it be possible to document that fact — and, better still, provide some examples demonstrating the relationship — to the Stages & Matrixes docs?

We will get to that shortly! :slight_smile:

1 Like

Also, does that mean that if a jobs.include.stage has no script or install or the like, that it will inherit them from the default stage?

Not quite sure what you mean. Could you use some examples to show what you have in mind?

In this example:

language: perl
perl:
  - "5.28"
  - "5.26"
script: perl -E 'say $ENV{PGVERSION}'
jobs:
  include:
    stage: Special
    env: PGVERSION=10

Will the “Special” stage execute the script from the default stage (perl -E 'say $ENV{PGVERSION}'), or will it do something else for the script?

In this example, yes. The job in jobs.include will inherit script defined at the top level.

And the same would be true of other fields, like before_install, install, etc.?

Affirmative!

1 Like

With the insight from @BanzaiMan that jobs is an alias for matrix, I was able to get the behavior I expected by eschewing the matrix in favor of jobs like so:

language: perl
perl:
  - "5.28"
  - "5.26"
env: PGVERSION=system
script: perl -E 'say $ENV{PGVERSION}'
jobs:
  include:
    - { env: PGVERSION=11 }
    - { env: PGVERSION=10 }
    - { stage: Special }