Dynamic outputs for job with strategy.matrix

I have a package that is a core dependency of multiple other packages within my organization. My goal is to write an action to automate/ facilitate testing of these reverse dependencies. Roughly, the action should:

  1. Trigger on a comment in a PR.
  2. Run the unit tests of a set of reverse-dependencies with the code in that PR.
  3. Reply to the PR with a comment about which tests failed (if any).

Steps 1 and 3 I got to work, but I’m running into issues with step 2. I would like to avoid hardcoding all job outputs to pass the results from step 2 to step 3.

The following example workflow illustrates my problem:

name: Test
on: push

jobs:
  unit-tests:
    runs-on: ${{ matrix.os }}
    continue-on-error: true

    name: ${{ matrix.os }} (${{ matrix.pkg }})

    strategy:
      fail-fast: false
      matrix:
        # there will be more pkgs and OSes
        os: [ubuntu-latest]
        pkg: [pkgA, pkgB]

    # how to avoid hardcoding these?
    outputs:
      ubuntu-latest-pkgA: ${{ steps.update-output.outputs.ubuntu-latest-pkgA }}
      ubuntu-latest-pkgB: ${{ steps.update-output.outputs.ubuntu-latest-pkgB }}     
  
    steps:
      - uses: actions/checkout@v2
      
      - name: fake unit tests
        run: |
          exit 1 # fail all tests for now
        shell: bash

      - name: set error if tests fail
        id: update-output
        if: ${{ failure() }}
        run: echo "::set-output name=${{ matrix.os }}-${{ matrix.pkg }}::error"
        shell: bash

  aggregate-results:
    runs-on: ubuntu-latest
    needs: unit-tests
    steps:
      - name: Aggregate results
        env:
          NEEDS: ${{ toJSON(needs) }}
        run: echo "$NEEDS"

The job aggregate-results (inspired by [BUG] Jobs output should return a list for a matrix job - #24 by umidbekk) works nicely and prints:

{
  "unit-tests": {
    "result": "success",
    "outputs": {
      "ubuntu-latest-pkgA": "error",
      "ubuntu-latest-pkgB": "error"
    }
  }
}

which I can use to create an informative comment. However, the job unit-tests requires me to hardcode the outputs for all combinations of os and pkg. Is there a way to do this dynamically? For what it’s worth, the only thing I want to know is which combination(s) of os and pkg failed.