How to share workspace between independents jobs

Hello,

I am running Cypress tests in parallel, and each test generates a JUnit report. At the end of the execution of all instances, I need to launch a job that merges all the reports into one.

The problem is that if I configure my process_test_results job to depend on cypress_tests_linux, the process_test_results job is not launched if cypress_tests_linux fails. I tried adding a waiter job to wait for the completion of the cypress_tests_linux job before launching process_test_results. However, the workspace is empty when it is attached to the process_test_results job.

Can you suggest a solution to ensure that the process_test_results job runs and has access to the JUnit reports, even if the cypress_tests_linux job fails?

version: 2.1

orbs:
  cypress: cypress-io/cypress@3.3.1
  aws-ecr: circleci/aws-ecr@7.3.0

executors:
  cypress-base-image:
    docker:
      - image: "ecr:cypress-ci-1.0-20240527"
        aws_auth:
          aws_access_key_id: $AWS_ACCESS_KEY_ID
          aws_secret_access_key: $AWS_SECRET_ACCESS_KEY

commands:
  persist_ws:
    steps:
      - run:
          name: Debug before persisting workspace
          command: ls -la ~/workspace/test-output
      - persist_to_workspace:
          root: ~/workspace
          paths:
            - test-output

  attach_ws:
    steps:
      - attach_workspace:
          at: ~/workspace

  cypress_tests:
    parameters:
      browser:
        type: string
        default: chrome
      specPattern:
        type: string
        default: ""
      ciBuildId:
        type: string
      group:
        type: string
      isMobile:
        type: boolean
        default: false
    
    steps:
      - attach_ws
      - when:
          condition:
            and:
              - equal: [true, << parameters.isMobile >>]
          steps:
            - cypress/run-tests:
                cypress-command: npx cypress run --ci-build-id=<<parameters.ciBuildId>> --group="<<parameters.group>>" --record --parallel --spec=<<parameters.specPattern>> --browser=<<parameters.browser>> --env sizes='["iphone-xr"]'
      - when:
          condition:
            and:
              - equal: [false, << parameters.isMobile >>]
          steps:
            - cypress/run-tests:
                cypress-command: npx cypress run --ci-build-id=<<parameters.ciBuildId>> --group="<<parameters.group>>" --record --parallel --spec=<<parameters.specPattern>> --browser=<<parameters.browser>> --reporter custom-package-xray-cypress-report --reporter-options mochaFile=test-output/test-results.[hash].xml
            - run:
                name: Copy Test Results to Workspace
                command: |
                  mkdir -p ~/workspace/test-output
                  ls
                  cp -r test-output/* ~/workspace/test-output/
                when: always
            - persist_ws
            - verify_persisted_results

  verify_persisted_results:
    steps:
      - attach_ws
      - run:
          name: Verify Persisted Results
          command: |
            echo "Checking persisted test results..."
            ls -la ~/workspace/test-output
          when: always

jobs:
  process_test_results:
      executor: cypress-base-image
      steps:
        - verify_persisted_results

  waiter:
    docker: 
      - image: cimg/node:18.20.2
    steps:
      - run: |
          while [[ $(curl --location --request GET "https://circleci.com/api/v2/workflow/$CIRCLE_WORKFLOW_ID/job" --header "Circle-Token: $CCI_Token"| jq -r '.items[]|select(.name != "waiter")|.status' | grep -c "running") -gt 0 ]]
            do
              sleep 8
            done
      - run: echo "All required jobs have now completed"

  checkout_and_set_env:
    docker:
      - image: cimg/node:18.20.2
    working_directory: ~/workspace
    steps:
      - checkout
      - run:
          name: Fetch Git Information
          command: |
            echo "COMMIT_INFO_BRANCH=${CIRCLE_BRANCH}" >> ~/workspace/env-vars.sh
            echo "COMMIT_INFO_MESSAGE=$(git log -1 --pretty=%B)" >> ~/workspace/env-vars.sh
            echo "COMMIT_INFO_EMAIL=$(git log -1 --pretty=%ae)" >> ~/workspace/env-vars.sh
            echo "COMMIT_INFO_AUTHOR=$(git log -1 --pretty=%an)" >> ~/workspace/env-vars.sh
            echo "COMMIT_INFO_SHA=${CIRCLE_SHA1}" >> ~/workspace/env-vars.sh
            echo "COMMIT_INFO_REMOTE=${CIRCLE_REPOSITORY_URL}" >> ~/workspace/env-vars.sh
      - run:
          name: Set Permissions on env-vars.sh
          command: chmod 644 ~/workspace/env-vars.sh
      - run:
          name: Verify env-vars.sh creation
          command: |
            cat ~/workspace/env-vars.sh
            ls -la ~/workspace
      - persist_to_workspace:
          root: ~/workspace
          paths:
            - env-vars.sh

  cypress_tests_linux:
    executor: cypress-base-image
    working_directory: /usr/src/cnc/
    environment:
      DEBUG: "commit-info,cypress:server:record"
    parallelism: 2
    parameters:
      browser:
        type: string
        default: chrome
      specPattern:
        type: string
        default: ""
      ciBuildId:
        type: string
      group:
        type: string
      isMobile:
        type: boolean
        default: false
    steps:
      - attach_workspace:
          at: ~/workspace
      - run:
          name: Set and Print Environment Variables
          command: |
            echo "Setting environment variables"
            export COMMIT_INFO_BRANCH=$(grep 'COMMIT_INFO_BRANCH' ~/workspace/env-vars.sh | cut -d '=' -f2)
            export COMMIT_INFO_MESSAGE=$(grep 'COMMIT_INFO_MESSAGE' ~/workspace/env-vars.sh | cut -d '=' -f2)
            export COMMIT_INFO_EMAIL=$(grep 'COMMIT_INFO_EMAIL' ~/workspace/env-vars.sh | cut -d '=' -f2)
            export COMMIT_INFO_AUTHOR=$(grep 'COMMIT_INFO_AUTHOR' ~/workspace/env-vars.sh | cut -d '=' -f2)
            export COMMIT_INFO_SHA=$(grep 'COMMIT_INFO_SHA' ~/workspace/env-vars.sh | cut -d '=' -f2)
            export COMMIT_INFO_REMOTE=$(grep 'COMMIT_INFO_REMOTE' ~/workspace/env-vars.sh | cut -d '=' -f2)
            echo "COMMIT_INFO_BRANCH: $COMMIT_INFO_BRANCH"
            echo "COMMIT_INFO_MESSAGE: $COMMIT_INFO_MESSAGE"
            echo "COMMIT_INFO_EMAIL: $COMMIT_INFO_EMAIL"
            echo "COMMIT_INFO_AUTHOR: $COMMIT_INFO_AUTHOR"
            echo "COMMIT_INFO_SHA: $COMMIT_INFO_SHA"
            echo "COMMIT_INFO_REMOTE: $COMMIT_INFO_REMOTE"
            # Set these variables for the next steps
            echo "export COMMIT_INFO_BRANCH=$COMMIT_INFO_BRANCH" >> $BASH_ENV
            echo "export COMMIT_INFO_MESSAGE=$COMMIT_INFO_MESSAGE" >> $BASH_ENV
            echo "export COMMIT_INFO_EMAIL=$COMMIT_INFO_EMAIL" >> $BASH_ENV
            echo "export COMMIT_INFO_AUTHOR=$COMMIT_INFO_AUTHOR" >> $BASH_ENV
            echo "export COMMIT_INFO_SHA=$COMMIT_INFO_SHA" >> $BASH_ENV
            echo "export COMMIT_INFO_REMOTE=$COMMIT_INFO_REMOTE" >> $BASH_ENV
            source $BASH_ENV
      - cypress_tests:
          browser: <<parameters.browser>>
          specPattern: <<parameters.specPattern>>
          ciBuildId: <<parameters.ciBuildId>>
          group: <<parameters.group>>
          isMobile: <<parameters.isMobile>>

linux-workflow: &linux-workflow
  jobs:
    - checkout_and_set_env
    - cypress_tests_linux:
        name: "UI Tests - Chrome"
        browser: chrome
        specPattern: "./cypress/e2e/AccountManagement/AccountManagement.cy.js"
        ciBuildId: ${CIRCLE_SHA1:0:8}
        group: "UI - Chrome"
        context:
          - tbst-build
          - cypress-secrets
        requires:
          - checkout_and_set_env
    # - cypress_tests_linux:
    #     name: "UI Tests - Firefox"
    #     browser: firefox
    #     specPattern: "./cypress/e2e/AccountManagement/AccountManagement.cy.js"
    #     ciBuildId: ${CIRCLE_SHA1:0:8}
    #     group: "UI - Firefox"
    #     context:
    #       - tbst-build
    #       - cypress-secrets
    #     requires:
    #       - checkout_and_set_env
    - waiter:
        context:
          - cnc-circleci-pat

    - process_test_results:
        context:
          - tbst-build
        requires:
          - waiter

workflows:
  linux:
    <<: *linux-workflow