0

Goal

I would like to run a Github actions workflow that has multiple jobs. I would like those jobs to have as little duplication as possible (I've come to accept that some duplication may be unavoidable).

Current solution

My first job (build-dev) installs dependencies and my second job (unit-test) runs my unit tests. The code is:

jobs:
  build-dev:

    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          architecture: ${{ env.ARCHITECTURE }}
          cache: pipenv
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Display Python version
        run: python -c "import sys; print(sys.version)"

      - name: Install Pipenv
        run: python -m pip install --upgrade pipenv

      - name: Install dependencies
        run: pipenv install --dev

  unit-test:

    runs-on: ubuntu-latest
    needs: build-dev

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          architecture: ${{ env.ARCHITECTURE }}
          cache: pipenv
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Install Pipenv
        run: python -m pip install --upgrade pipenv

      - name: Unit test
        run: pipenv run unit-test

Expected solution

Ideally, I'd like my second job (unit-test) to have access to the tools added to the runner used in my first job (build-dev). I'd expect the code to look something like this:

jobs:
  build-dev:

    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          architecture: ${{ env.ARCHITECTURE }}
          cache: pipenv
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Display Python version
        run: python -c "import sys; print(sys.version)"

      - name: Install Pipenv
        run: python -m pip install --upgrade pipenv

      - name: Install dependencies
        run: pipenv install --dev

  unit-test:

    runs-on: ubuntu-latest
    needs: build

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python ${{ env.PYTHON_VERSION }}
        uses: actions/setup-python@v4
        with:
          architecture: ${{ env.ARCHITECTURE }}
          cache: pipenv
          python-version: ${{ env.PYTHON_VERSION }}

      - name: Unit test
        run: pipenv run unit-test

Note the removal of the Install Pipenv step in the second job.

Currently, using the code above results in the error:

Run pipenv run unit-test
/home/runner/work/_temp/ef4fd997-0bb7-4623-8a8e-9aeb9fb6192d.sh: line 1: pipenv: command not found
Error: Process completed with exit code 127.

due to Pipenv not being installed on the second runner.

What I've tried

As you can see from the above code, I've attempted caching. This seems to specifically cache the dependencies installed by pipenv, and not pipenv itself.

Previously, I've uploaded an artifact, and used the global env var PIPENV_VENV_IN_PROJECT=enabled to effectively do the same as caching. Again, the same happened. I kept the installed dependencies and not the installed tools. I guess, I could artifact the runners /bin but the seems heavyweight and sounds like it could cause problems.

Some further thoughts

Please correct me if I'm wrong here, Isn't the point of CI/CD tooling to build packages and push that package through a pipeline? It feels to me like Github Actions design is specifically structured around re-pulling the code, re-installing deps, re-doing all the things you shouldn't be doing multiple times in a 'pipeline'.

I do understand the the commit SHA obviously ensures the code is consistent with each pull, but still, it feels to me like it's not a pipeline.

For an analogy, you wouldn't produce oil in the Middle East, and 'pipeline' it to Europe, but at every pipeline junction just pour the oil away and re-dig for new (possibly the same) oil.

Joe
  • 678
  • 9
  • 24

0 Answers0