Matrix expansion with explicit jobs is not done unless I define an empty stage

I ran into a situation similar to Config with a python build and a matrix only runs the matrix with the jobs matrix. The following config ended up with no jobs specified:

---
language: python
os:
- linux
python:
- "3.8"

stages:
- test
- name: deploy
  if: tag IS present

install:
- pip install --upgrade pip setuptools wheel tox tox-travis
script:
- tox -- --cov-report=xml
after_success:
- bash <(curl -f https://codecov.io/bash)

jobs:
  fast_finish: true
  include:
  - stage: deploy
    python: "3.8"
    install:
    - pip install --upgrade setuptools wheel
    script: skip
    after_success: "Deploying..."
    deploy:
    - provider: pypi
      cleanup: false
      distributions: sdist bdist_wheel
      username: $PYPI_USERNAME
      password: $PYPI_PASSWORD
      on:
        tags: true
        repo: $GITHUB_REPO
    - provider: releases
      cleanup: false
      token: $GITHUB_TOKEN
      on:
        tags: true
        repo: $GITHUB_REPO

but when I include an empty stage: test it works.

---
language: python
os:
- linux
python:
- "3.8"

stages:
- test
- name: deploy
  if: tag IS present

install:
- pip install --upgrade pip setuptools wheel tox tox-travis
script:
- tox -- --cov-report=xml
after_success:
- bash <(curl -f https://codecov.io/bash)

jobs:
  fast_finish: true
  include:
  - stage: test
  - stage: deploy
    python: "3.8"
    install:
    - pip install --upgrade setuptools wheel
    script: skip
    after_success: "Deploying..."
    deploy:
    - provider: pypi
      cleanup: false
      distributions: sdist bdist_wheel
      username: $PYPI_USERNAME
      password: $PYPI_PASSWORD
      on:
        tags: true
        repo: $GITHUB_REPO
    - provider: releases
      cleanup: false
      token: $GITHUB_TOKEN
      on:
        tags: true
        repo: $GITHUB_REPO

In the first configuration, you are defining two stages, test and deploy. The former is empty in all cases, and the latter is skipped unless it is a tagged build. You are defining a single job in jobs.include in the deploy stage. As a result, your configuration yields no jobs unless it is a tagged build.

In other words, everything is working as expected.

Well, the confusion is that if I specify:

python:
- "3.7"
- "3.8"

without

jobs:
  include:
  - stage: test

it works as expected. It creates two test runs and if there is a tag, it runs the deploy. So as the OP says, I find this part not very intuitive.

python:
- "3.7"
- "3.8"

defines two jobs in the default test stage, which is no longer empty, so the build runs.

I just don’t understand why

python:
- "3.8"

doesn’t equally define 1 job but creates an “empty” specification :man_shrugging: