Я создаю образы Docker с помощью Github Actions и хочу пометить образы именем ветки.

Я нашел переменную GITHUB_REF, но в результате получается refs / Heads / feature-branch-1, и мне нужно только feature-branch-1.

aborilov

Ответов: 22

Ответы (22)

Я добавил отдельный шаг для извлечения имени ветки из $ GITHUB_REF и установил его на вывод шага

- имя: Извлечь название ветки
  оболочка: bash
  run: echo "## [set-output name = branch;] $ (echo $ {GITHUB_REF # refs / Heads /})"
  id: extract_branch

после этого я могу использовать его в следующих шагах с

- имя: Отправить в ECR
  id: ecr
  использует: jwalton /gh-ecr-push@master
  с участием:
    идентификатор-ключа-доступа: $ {{secrets.AWS_ACCESS_KEY_ID}}
    секретный ключ доступа: $ {{secrets.AWS_SECRET_ACCESS_KEY}}
    регион: us-west-2
    image: eng: $ {{steps.extract_branch.outputs.branch}}

Теперь $ {{github.ref}} - это правильный способ получить имя ветки. Помните, что $ {{github.ref}} имеет refs / Heads /.. префикс

Чтобы установить его как переменную среды, я использую следующий синтаксис:

- name: Extract branch name
  shell: bash
  run: echo "::set-env name=BRANCH_NAME::$(echo ${GITHUB_REF#refs/heads/} | sed 's/\//_/g')"
- name: Test
  run: echo "${BRANCH_NAME}"

Я нашел здесь этот синтаксис: Действия Github - начальные рабочие процессы # Как определить переменную env? # 68

Rmq: sed 's / \ // _ / g' заменяет / на _ в ветке имя

Имейте в виду, что если вы выполняете действие GitHub по триггеру запроса на вытягивание, тогда переменная GITHUB_REF будет содержать что-то вроде refs / pull / 421 / merge, поэтому, если вы попытаетесьgit push на это имя, скорее всего, не удастся.

То, что вы можете использовать, это ссылки на контекст GitHub в вашем YAML. Примерно так: $ {{github.head_ref}}

https://help.github.com/en/actions/automating-your-workflow-with-github-actions/contexts-and-expression-syntax-for-github-actions#github-контекст

Github action context refs

Действие GitHub FranzDiebold / github-env-vars-action предоставляет несколько полезных переменных среды, таких как имя текущей ветки и их служебные значения. Я сделал это действие именно для этого варианта использования.

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

steps:
  - uses: FranzDiebold/github-env-vars-action@v1.2.0
  - name: Print environment variables
    run: |
      echo "GITHUB_REPOSITORY_SLUG=$GITHUB_REPOSITORY_SLUG"
      echo "GITHUB_REPOSITORY_OWNER=$GITHUB_REPOSITORY_OWNER"
      echo "GITHUB_REPOSITORY_OWNER_SLUG=$GITHUB_REPOSITORY_OWNER_SLUG"
      echo "GITHUB_REPOSITORY_NAME=$GITHUB_REPOSITORY_NAME"
      echo "GITHUB_REPOSITORY_NAME_SLUG=$GITHUB_REPOSITORY_NAME_SLUG"
      echo "GITHUB_REF_SLUG=$GITHUB_REF_SLUG"
      echo "GITHUB_REF_NAME=$GITHUB_REF_NAME"
      echo "GITHUB_REF_NAME_SLUG=$GITHUB_REF_NAME_SLUG"
      echo "GITHUB_SHA_SHORT=$GITHUB_SHA_SHORT"

enter image description here

Демо для всех операционных систем (Linux, macOS и Windows) также доступно в файле демонстрационных рабочих процессов репозитория!

Как получить текущую ветку в Github Actions?

Предполагая, что $ {{github.ref}} - это что-то вроде refs / Heads / mybranch, вы можете извлечь имя ветки, используя следующий метод:

steps:
  - name: Prints the current branch name
    run: echo "${GITHUB_BRANCH##*/}"
    env:
      GITHUB_BRANCH: ${{ github.ref }}

Если ваша ветка включает косые черты (например, feature / foo), используйте следующий синтаксис:

steps:
  - name: Prints the current branch name
    run: echo "${GITHUB_REF#refs/heads/}"

Кредиты: @ rmunn comment

Или используйте метод из принятого ответа, вот гораздо более короткая версия (без ворса):

steps:
  - name: Get the current branch name
    shell: bash
    run: echo "::set-output name=branch::${GITHUB_REF#refs/heads/}"
    id: myref

Затем на других этапах назовите $ {{steps.myref.outputs.branch}}.

Примечания:

${{ github.ref_name }}

Кажется, нормально работает для толчков минимум.

Вот фрагмент, который устанавливает переменную среды на основе $ GITHUB_REF, который по умолчанию равен dev, если отсутствует.

Настройте команду sed в соответствии с вашими требованиями.

экспорт GIT_BRANCH = $ (echo $ {GITHUB_REF: -dev} | sed s /.*\\/// g)

Для людей, использующих образ Windows для выполнения действий, несколько ключевых моментов, о которых следует знать:

  1. Неверно предполагать, что действия GitHub используют оболочку CMD. Они по умолчанию используют PowerShell.
  2. Вы можете указать оболочку для использования следующим образом:
- run: |
    ...
  shell: cmd
  1. Вы можете использовать значение 'bash' для выполнения команды в контексте оболочки bash.

Итак, в общем, вам не нужно тратить потенциально часы, пытаясь понять, как делать что-то в ветхом стиле cmd (как это сделал я).

И для простой цели получения имени текущей ветки вы можете либо использовать популярные решения при установке оболочки на 'bash', либо использовать, например, следующий простой способ установить переменную в оболочке PowerShell по умолчанию :

$ branchName = $ Env: GITHUB_REF - заменить "refs / Heads /", ""

Я сделал действие, которое получает имя ветки независимо от триггера pull_request или нет.https://github.com/EthanSK/git-branch-name-action

Работает в Windows ?. Команда Windows по умолчанию - это терминал PowerShell.

  - name: SET CURRENT_BRANCH
    run: |
      $branchName = "${{github.ref}}".Split("/")["${{github.ref}}".Split("/").Length -1]
      echo "::set-env name=CURRENT_BRANCH::$(echo $branchName)"

Чтобы также иметь дело с событием pull_request (в этом случае $ GITHUB_REF содержит что-то бесполезное, например refs / pull / 519 / merge), вы можете используйте этот лайнер:

   - name: Set branch name
     run: echo "::set-output name=branch_name::$(echo ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}})"

Если вы используете V2 из actions / checkout, вы всегда можете просто запустить git branch --show-current, чтобы просто получить имя ветки, которая в настоящее время проверена.

if: github.ref == 'refs/heads/integration' && github.event_name == 'push' 

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

Вы можете использовать https://github.com/rlespinasse/github-slug-action

# Just add this  => 
- name: Inject slug/short variables
  uses: rlespinasse/github-slug-action@v3.x



# And you get this  => 
- name: Print slug/short variables
  run: |
    echo "Slug variables"
    echo " - ${{ env.GITHUB_REF_SLUG }}"    
    echo " - ${{ env.GITHUB_HEAD_REF_SLUG }}"
    echo " - ${{ env.GITHUB_BASE_REF_SLUG }}"
    echo " - ${{ env.GITHUB_REPOSITORY_SLUG }}"
    # output e.g. : master feat-new-feature v1.0.0 product-1.0.0-rc.2 new-awesome-product
    echo "Slug URL variables"
    echo " - ${{ env.GITHUB_REF_SLUG_URL }}"
    echo " - ${{ env.GITHUB_HEAD_REF_SLUG_URL }}"
    echo " - ${{ env.GITHUB_BASE_REF_SLUG_URL }}"
    echo " - ${{ env.GITHUB_REPOSITORY_SLUG_URL }}"
    # output e.g. : master feat-new-feature v1-0-0 product-1-0-0-rc-2 new-awesome-product
    echo "Short SHA variables"
    echo " - ${{ env.GITHUB_SHA_SHORT }}"
    # output e.g. : ffac537e

Использование setenv - это , теперь устарело. Рекомендуется использовать файлы окружения. Основываясь на @ youjin answer, но при этом разрешая feature / ветки (заменяя все вхождения / на -), теперь я использую это:

вакансий:
  строить:
    работает: ubuntu-latest
    шаги:
      - name: получить название ветки (объединить)
        если: github.event_name! = 'pull_request'
        оболочка: bash
        run: echo "BRANCH_NAME = $ (echo $ {GITHUB_REF # refs / Head /} | tr / -)" >> $ GITHUB_ENV

      - name: получить название ветки (запрос на вытягивание)
        если: github.event_name == 'pull_request'
        оболочка: bash
        запустить: echo "BRANCH_NAME = $ (echo $ {GITHUB_HEAD_REF} | tr / -)" >> $ GITHUB_ENV

      - имя: Отладка
        запустить: echo $ {{env.BRANCH_NAME}}

Использовать имя ветки в действиях GitHub

Удобное действие для использования текущего имени ветки. Использование

name: build
on: push

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - run: npm ci
    - uses: nelonoel/branch-name@v1
    # Use branch name for whatever purpose
    - run: echo ${BRANCH_NAME}

Вот полный рабочий процесс, который работает как для push, так и pull_request событий

имя: whichBranch
на: [pull_request, push]

вакансии:
  which_branch:
    работает: ubuntu-latest
    шаги:
      - name: извлекать имя ветки при нажатии
        если: github.event_name! = 'pull_request'
        оболочка: bash
        run: echo ":: set-env name = BRANCH_NAME :: $ (echo $ {GITHUB_REF # refs / Head /})"
        id: extract_branch

      - name: Извлечь имя ветки при запросе на вытягивание
        если: github.event_name == 'pull_request'
        запустить: echo ":: set-env name = BRANCH_NAME :: $ (echo $ {GITHUB_HEAD_REF})"

      - name: Распечатать название ветки
        run: echo 'Имя ветки -' $ BRANCH_NAME

Я только что провел простой тест в пределах GitHub Actions с использованием сценария bash:

#! / Bin / bash

echo Зарезервировано для REPO_NAME = $ {GITHUB_REPOSITORY ## * /}
эхо GITHUB_REF = $ {GITHUB_REF}
эхо EXTRACT_GITHUB_REF = $ {GITHUB_REF ## * /}
эхо EXTRACT_GITHUB_REF_HEADS = $ (эхо $ {GITHUB_REF # ссылки / головы /})

cd $ REPO_NAME
git checkout $ {GITHUB_REF ## * /}
git checkout $ (эхо $ {GITHUB_REF # refs / Heads /})

Вот скриншот вывода:

enter image description here Итак, оба $ {GITHUB_REF ## * /} и $ (echo $ {GITHUB_REF # refs / Heads /}) верны

Обычно у меня всегда есть сценарий, написанный на nodejs или python, который вызывается из workflow.yaml. Сценарий обычно выполняет такие работы, как получение правильной ссылки на ветку.

У меня есть функция, как показано ниже, в prepare-deployment.js script-

const VALID_REF_PREFIX = 'ссылки / головы /';
...

function getBranchRef (isProd = false) {
  пусть BranchRef = 'origin / master';

  if (isProd) {
    return branchRef;
  }
  / **
   * Когда рабочий процесс вызывается из ручного потока, имя ветки
   * находится в GITHUB_REF, в противном случае нам нужно посмотреть GITHUB_BASE_REF
   * /
  если (GITHUB_REF.startsWith (VALID_REF_PREFIX)) {
    // поступает из ручного триггера рабочего процесса
    branchName = `origin / $ {GITHUB_REF.replace (VALID_REF_PREFIX, '')}`;
  } еще {
    // исходя из PR
    BranchRef = `origin / $ {GITHUB_HEAD_REF}`;
  }

  return branchRef;
}

Это касается следующих сценариев:

  1. Я хочу перенести изменения из PR в свой dev env
  2. Я хочу развернуть изменения из любой ветки, которую я хочу, в свой dev env, с помощью ручного триггера
  3. Я хочу перенести изменения из мастера в свой продукт env

Обновить

GitHub теперь поддерживает GITHUB_REF_NAME, что означает: Имя ветки или тега, которое инициировало запуск рабочего процесса.

Документы GitHub об этом https://docs.github.com/en/actions/learn-github-actions/environment-variables

Я считаю, что GITHUB_REF - единственная переменная среды, которая включает имя ветки.

Вы можете извлечь только имя ветки из остальной части этой строки следующим образом:

${GITHUB_REF##*/}

Пример:

$ GITHUB_REF=refs/heads/feature-branch-1
$ echo ${GITHUB_REF##*/}
feature-branch-1

Обновление: добавлен полный пример рабочего процесса.

Рабочий процесс

name: CI
on: push
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Git checkout
        uses: actions/checkout@v1
      - name: Branch name
        run: echo running on branch ${GITHUB_REF##*/}
      - name: Build
        run: docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .

Источник: https://github.com/tedmiston/x/blob/master/.github/workflows/workflow.yml

Пример вывода - главная ветвь

Run docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  shell: /bin/bash -e {0}
Sending build context to Docker daemon  146.9kB

Step 1/1 : FROM alpine
latest: Pulling from library/alpine
9d48c3bd43c5: Pulling fs layer
9d48c3bd43c5: Verifying Checksum
9d48c3bd43c5: Download complete
9d48c3bd43c5: Pull complete
Digest: sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb
Status: Downloaded newer image for alpine:latest
 ---> 961769676411
Successfully built 961769676411
Successfully tagged tedmiston/tag-example:master

Журнал: https://github.com/tedmiston/x/commit/cdcc58a908e41d3d90c39ab3bf6fef1ad2c4238a/checks#step: 4: 16

Пример вывода - не главная ветвь

Run docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  docker build -t tedmiston/tag-example:${GITHUB_REF##*/} .
  shell: /bin/bash -e {0}
Sending build context to Docker daemon  144.9kB

Step 1/1 : FROM alpine
latest: Pulling from library/alpine
9d48c3bd43c5: Pulling fs layer
9d48c3bd43c5: Verifying Checksum
9d48c3bd43c5: Download complete
9d48c3bd43c5: Pull complete
Digest: sha256:72c42ed48c3a2db31b7dafe17d275b634664a708d901ec9fd57b1529280f01fb
Status: Downloaded newer image for alpine:latest
 ---> 961769676411
Successfully built 961769676411
Successfully tagged tedmiston/tag-example:branch-name-test

Журнал: https://github.com/tedmiston/x/commit/4e8d31259f861aaa2c30375756fc081c3659bddf/checks#step: 4: 16


См. этот ответ для получения дополнительной информации о синтаксисе расширения параметров.

Для справки: на странице Виртуальные среды для действий GitHub перечислены все переменные среды, доступные в среде выполнения.

2022 WebDevInsider