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

В Github Actions данные не являются по своей природе постоянными и широкодоступными. Каждый шаг выполняется в своем собственном процессе, каждое задание — в своем бегуне, и по умолчанию любые данные, возникающие в рабочем процессе, умирают вместе с ним.

В этом посте мы поделимся любовью и данными вокруг вашего GitHub CI :P

TL,DR;

Использование окружения

Передача данных между шагами довольно проста: определите свое значение в паре ключ-значение и запишите его в файл среды GITHUB_ENV, используя соответствующий синтаксис вашей оболочки. В оболочке bash это будет выглядеть так:

steps:
  - name: Setting value
    run: |
      echo "colour=yellow" >> $GITHUB_ENV

  - name: Retrieving value
    # Security tip: It's an overkill here, but this is how input sanitization 
    # happens in GitHub Actions: pass the value to your script via 
    # an intermediate environment variable (in this case, MY_COLOUR)
    env:
      MY_COLOUR: ${{ env.colour }}
    run: echo "$MY_COLOUR"

    

Использование outputs

  • Вывод будет доступен всем зависимым заданиям, которые появятся позже (зависимые задания имеют ключ needs).
  • Выходные данные представляют собой строку Юникода размером не более 1 МБ. Все выходные данные в рабочем процессе могут иметь размер не более 50 МБ.
  • Выходные данные, содержащие секреты, редактируются на бегуне и не покидают бегун.
  • По логическим причинам требование вывода не позволит зависимым заданиям выполняться параллельно с заданием, создающим выходные данные.
jobs:
  extract-name:
    runs-on: ubuntu-latest
    outputs:
      person_name: ${{ steps.generate-name.outputs.name }}
      person_surname: ${{ steps.generate-surname.outputs.surname }}
    steps:
      - id: generate-name
        run: echo "name=Luiza" >> "$GITHUB_OUTPUT"
      - id: generate-surname
        run: echo "surname=Mahin" >> "$GITHUB_OUTPUT"
  job2:
    runs-on: ubuntu-latest
    needs: extract-name
    steps:
      - env:
          person_name: ${{needs.job1.outputs.person_name}}
          person_surname: ${{needs.job1.outputs.person_surname}}
        run: echo "$person_name $person_surname"

Использование артефактов

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

- name: Run benchmark
        run: |
          mvn clean package -B -Dstyle.color=always -DskipTests=true --file pom.xml
          java -Dlog4j.configurationFile=benchmarks/log4j2.xml -Xms8g -Xmx8g -jar benchmarks/target/benchmarks.jar -wi 5 -i 5 -f 1 -rf json
      - name: Upload JHM results
        uses: actions/upload-artifact@v3
        with:
          name: jmh-result.json
          path: jmh-result.json

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

Кроме того, максимальные сроки хранения могут быть определены на уровне репо, организации или предприятия. (подсказка: максимум 90 дней для публичных репозиториев и 400 дней для частных репозиториев. Возможно, вы захотите уменьшить этот срок, чтобы освободить для вас больше места!)

- name: Upload log files
  uses: actions/upload-artifact@v3
	with:
	  name: logs-artifact
	  path: |
		**/logs.json
		!**/tests/** # exclude all files in the tests folder
	  retention-days: 5

Использование кеша

  • Не храните конфиденциальную информацию в кеше (остерегайтесь конфигурационных файлов с секретами), так как кеш доступен любому, кто может создать PR на репозитории, даже на форках.
  • Если вы используете автономные средства запуска, возможность самостоятельного хранения кеша доступна только в планах Enterprise.
  • Подробнее о стратегиях кэширования читайте здесь.
- name: Set up cache for Python dependencies
	  uses: actions/cache@v3
	  id: cache
	  with:
	    path: ~/.cache/pip
	    key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
- name: Install dependencies if not found in cache
   # The conditional below is not necessary for Python, as pip 
   # will not reinstall dependencies if they are already there.
   # This is just to demo cache usage
   if: steps.cache.outputs.cache-hit != 'true' || inputs.no_cache == 'true'
   run: pip install -r requirements.txt

hashFiles здесь очень хорошо используется. Это функция, предоставляемая GitHub Actions, которая создает уникальное значение хеш-функции на основе пути к файлу. Таким образом, если значение хеш-функции не совпадает (то есть зависимости изменились), кеш не используется, а вместо этого обновляется после переустановки зависимостей в задании посткэширования.

Удачной конвейерной обработки :)