Передача данных между заданиями CI/CD SourceCraft

В CI/CD SourceCraft вы можете передавать данные между заданиями. Для этого:

  1. В исходном задании, из которого вы хотите передать информацию, в скрипте кубика запишите выходные данные в формате ключ=значение в предопределенную переменную окружения SOURCECRAFT_OUTPUT, например:

    workflows:
      tasks-outputs-workflow:
        tasks:
          - name: producer
            cubes:
              - name: build
                script:
                  - |
                    echo "BUILD_RESULT=hello-world" >> $SOURCECRAFT_OUTPUT
                    echo "BUILD_VERSION=1.0.0" >> $SOURCECRAFT_OUTPUT
            ...
    
  2. В этом же задании в блоке outputs объявите список передаваемых переменных в формате <переменная>: ${{ cubes.<название_кубика>.outputs.<ключ_из_кубика> }}, например:

    workflows:
      tasks-outputs-workflow:
        tasks:
          - name: producer
            ...
            outputs:
              PRODUCER_RESULT: ${{ cubes.build.outputs.BUILD_RESULT }}
              PRODUCER_VERSION: ${{ cubes.build.outputs.BUILD_VERSION }}
    
  3. В задании, в которое вы хотите передать информацию, добавьте в список needs зависимость от исходного задания в формате needs: [<название_задания>], например:

    workflows:
      tasks-outputs-workflow:
        tasks:
          - name: producer
            ...
          - name: consumer
            needs: [producer]
            ...
    

    Важно

    Параметр needs можно использовать только внутри блока workflows:tasks. Не допускается использовать в отдельном блоке tasks.

    В поле needs можно сослаться только на задания рабочего процесса, внутри которого выполняется текущее задание. Циклические зависимости не допускаются.

  4. В кубике зависимого задания получите данные с помощью выражения ${{ tasks.<имя_задания>.outputs.<ключ_из_задания> }}. Выражение можно использовать в скриптах, переменных окружения и блоке outputs. Пример:

    workflows:
      tasks-outputs-workflow:
        tasks:
            ...
          - name: consumer
            ...
            cubes:
              - name: consume
                env:
                  VERSION: ${{ tasks.producer.outputs.PRODUCER_VERSION }}
                script:
                  - echo "${{ tasks.producer.outputs.PRODUCER_RESULT }}"
                  - echo "$VERSION"
    

    Важно

    В зависимом задании можно получить выходные значения только тех заданий, которые явно указаны в списке needs.

  5. Чтобы передать данные дальше по цепочке зависимостей, объявите транзитную переменную в блоке outputs промежуточного задания, например:

    workflows:
      tasks-outputs-workflow:
        tasks:
          - name: producer
            outputs:
              PRODUCER_RESULT: ${{ cubes.build.outputs.BUILD_RESULT }}
            ...
          - name: consumer
            needs: [producer]
            outputs:
              FORWARDED_RESULT: ${{ tasks.producer.outputs.PRODUCER_RESULT }}
            ...
          - name: next-consumer
            needs: [consumer]
            ...
    

Пример рабочего процесса с передачей данных между заданиями

В примере ниже:

  • Данные в переменной PT_RESULT из задания producer-task передаются и используются в заданиях consumer-producer-task и consumer-task-2.
  • Данные в переменных CPT_RESULT1 и CPT_RESULT2 из задания consumer-producer-task передаются и используются в заданиях consumer-task-1 и consumer-task-2.
workflows:
  tasks-outputs-workflow:
    checkout:
      enabled: false
    tasks:
      - name: producer-task
        # Секция, определяющая, какие данные могут быть использованы другими заданиями
        outputs:
          # Переменная, в которую будет записан результат задания
          # Значение переменной должно указывать на ключ, переданный в кубике в переменную SOURCECRAFT_OUTPUT
          # Имя переменной в outputs задания может не совпадать с ключом, переданным в кубике
          PT_RESULT: ${{ cubes.produce.outputs.PRODUCER_TASK_RESULT }}
        cubes:
          - name: produce
            script:
              # Передача в переменную окружения SOURCECRAFT_OUTPUT выходных данных кубика в формате ключ=значение
              # В значениях можно указывать любые символы, включая специальные
              - echo "PRODUCER_TASK_RESULT=Результат задания producer-task — '🚀'" >> $SOURCECRAFT_OUTPUT

      - name: consumer-producer-task
        # Указание зависимости от задания producer-task для доступа к его результатам
        needs: [producer-task]
        # outputs могут быть определены в любом задании, в том числе зависимом
        outputs:
          CPT_RESULT1: ${{ cubes.consume-produce-1.outputs.CPT_RESULT1 }}
          CPT_RESULT2: ${{ cubes.consume-produce-2.outputs.CPT_RESULT2 }}
        cubes:
          - name: consume-produce-1
            env:
              UPSTREAM_RESULT: ${{ tasks.producer-task.outputs.PT_RESULT }}
            script:
              - echo "$UPSTREAM_RESULT"
              - echo "CPT_RESULT1=$UPSTREAM_RESULT и первый результат задания consumer-producer-task — '⭐'" >> $SOURCECRAFT_OUTPUT
          - name: consume-produce-2
            script:
              - LOCAL_VAR="${{ tasks.producer-task.outputs.PT_RESULT }}"
              - echo "${LOCAL_VAR}"
              - echo "CPT_RESULT2=Второй результат задания consumer-producer-task — '🔥'" >> $SOURCECRAFT_OUTPUT
          - name: consume
            script:
              - echo "${{ tasks.producer-task.outputs.PT_RESULT }}"

      - name: consumer-task-1
        needs: [consumer-producer-task]
        cubes:
          - name: consume
            script:
              # Поскольку в needs указано только задание consumer-producer-task, доступны данные только из него
              # Данные из задания producer-task недоступны
              - echo "${{ tasks.consumer-producer-task.outputs.CPT_RESULT1 }}"
              - echo "${{ tasks.consumer-producer-task.outputs.CPT_RESULT2 }}"

      - name: consumer-task-2
        needs: [producer-task, consumer-producer-task]
        cubes:
          - name: consume
            script:
              # В needs указаны задания producer-task и consumer-producer-task,
              # поэтому доступны данные из обоих заданий
              - echo "${{ tasks.consumer-producer-task.outputs.CPT_RESULT1 }}"
              - echo "${{ tasks.consumer-producer-task.outputs.CPT_RESULT2 }}"
              - echo "${{ tasks.producer-task.outputs.PT_RESULT }}"

Ограничения

  • Размер одной записи KEY=VALUE не должен превышать 64 КБ (65 536 байт).
  • Суммарный размер имен и значений всех выходных данных одного задания не должен превышать 1 МБ. При превышении лимита задание завершается с ошибкой, даже если все кубики выполнены успешно. Для передачи данных большего размера используйте артефакты.
  • Если выражение ${{ cubes.<название_кубика>.outputs.<ключ_из_кубика> }} или ${{ tasks.<название_задания>.outputs.<ключ_из_задания> }} ссылается на несуществующее значение, задание завершается с ошибкой.

Совет

Чтобы использовать выходные значения заданий на пользовательском воркере, обновите исполняемый файл воркера до версии 0.14.2 или выше.

Полезные ссылки