Инструменты пользователя

Инструменты сайта


develop:gh_actions

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Следующая версия
Предыдущая версия
develop:gh_actions [2024/01/26 05:25]
admin создано
develop:gh_actions [2024/02/19 03:46] (текущий)
admin
Строка 1: Строка 1:
 ====== GitHub Actions ====== ====== GitHub Actions ======
  
 +===== Введение =====
 +Сервис GitHub, который позволяет автоматизировать любой процесс связанный с деплоем кода на продакшн сервер. Код проекта выполняется на виртуальных серверах GH и далее доставляется куда нужно\\
  
 +<details>
 +<summary>:!: more</summary>
 +Имеет множество готовых решений, шаблонов и т.д.\\
 +Файлы располагаются во вложенной директории "./GitHub/workflows/.yml", файлы в формате yml\\
 +Можно работать в онлайн редакторе\\
 +</details>
  
-=====  ===== 
-=====  ===== 
-=====  ===== 
  
 +==== Workflow ====
 +Поток выполнения действий\\
 +Задачи внутри - джобы (**jobs**), которые состоят из шагов (**steps**)\\
  
 +<details>
 +<summary>:!: more</summary>
 +Workflow обычно выполняет какую то большую задачу (очевидно правильно разбивать "одна задача - один воркфлоу"), их может быть множество, могут выполняться как  последовательно так и параллельно, как и джобы\\
  
-====  ==== +Может быть вызван автоматически, вручную либо выполняться по расписанию\\ 
-====  ==== +Пример workflow:\\ 
-====  ====+<code yaml> 
 +name: Print workflow  
 +  # запуск вручную 
 +on: workflow_dispatch 
 + 
 +jobs:  
 +    # название джобы 
 +  print_hello: 
 +      # среда для запуска джобы 
 +    runs-on: ubuntu-latest 
 +     
 +    steps: 
 +      - name: Print hello 
 +          # команда которая будет выполнена в терминале 
 +        run: echo "Hello world"  
 +</code> 
 +В этом примере три логических блока:  
 +  * параметры самого воркфлоу (name и on (пар-р запуска)),  
 +  * настройка джоб (название и runs-on (инструкция для докера))  
 +  * и шаги (так же название и run (команда для выполнения)) 
 +</details> 
 + 
 + 
 + 
 +==== Jobs ==== 
 +"**Джобы выполняются** на разных VM", для выполнения в рамках одной VM есть **steps**\\
  
 <details> <details>
-<summary> </summary>+<summary>:!: Порядок выполнения jobs</summary> 
 + 
 +Параллельное выполнение 
 +<code yaml> 
 +jobs: 
 +  print_hello: 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: Print hello 
 +        run: echo "Hello world!" 
 +   
 +  print_full_tech_info: 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: print full_tech_info 
 +        run: sudo lshw 
 +   
 +  print_short_tech_info: 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: 
 +        run: sudo lshw -short 
 +</code> 
 +В интерфейсе GH, данные джобы будут в одном блоке, вместе, выполнялись параллельно\\ 
 + 
 +Для последовательного выполнения используется параметр "needs"\\ 
 +<code yaml> 
 +jobs: 
 +  print_hello: 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: print hello 
 +        run: echo "hello world"  
 + 
 +  print_full_tech_info: 
 +    needs: print_hello 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: print_full_tech_info 
 +        run: sudo lshw 
 + 
 +  print_short_tech_info: 
 +    needs: print_full_tech_info 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: print_short_tech_info 
 +        run: sudo lswh -short 
 +</code> 
 +В интерфейсе GH джобы будут размещены в разных блоках, друг за другом\\ 
 +Если одна из них завершится с ошибкой, то остальные выполняться не будут\\ 
 + 
 +Такие цепочки зависимостей можно строить и целыми workflow\\ 
 +<code yaml> 
 +name: my_Workflow 
 +  # секция условий выполнения текущего флоу 
 +on: 
 +  workflow_run: 
 +    workflows: ["Run tests"
 +    branches: [main] 
 +    types: 
 +        # статус выполнения первого флоу 
 +      - completed 
 +</code> 
 +</details> 
 + 
 + 
 + 
 +==== Actions ==== 
 +Вместо инструкции "**run**", для вызова команд, можно использовать готовые модули или решения, написанные другими разработчиками, они распространяются бесплатно на маркетплейсе GH\\ 
 + 
 +<details> 
 +<summary>:!: пример</summary> 
 +Например популярный экшен для загрузки кода из репозитория, "checkout@v3"\\ 
 + 
 +<code yaml> 
 +name: print workflow 
 +on: workflow_dispatch 
 + 
 +jobs: 
 +  checkout: 
 +    runs-on: ubuntu-latest 
 +    steps: 
 +      - name: checkout_repo 
 +        uses: actions/checkout@v3 
 +</code> 
 +</details> 
 + 
 + 
 + 
 +==== Примеры ==== 
 + 
 +<details> 
 +<summary>:!: Большой пример </summary> 
 +Главный экшен "ci-production" является точкой входа, внутри запускает доп экшены\\ 
 +Выполняются на self-hosted раннерах\\ 
 +Настроено несколько окружений, содержащих свой набор переменных, задаются в настройках репозитория\\ 
 + 
 + 
 + 
 +"ci-production.yml"\\ 
 +Триггеримся на пуш тега с формате "release-"\\ 
 +Нюанс в том что сработает пуш этого тега в любую ветку а выпуск релиза предполагается наверно из мастера\\
  
 <code bash> <code bash>
 +name: ci-production
 +on:
 +  push:
 +    tags:
 +      - 'release-*'
 +
 +jobs:
 +  build:
 +    uses: ./.github/workflows/build.yml
 +    secrets: inherit
 +
 +  deploy-stage:
 +    needs: build
 +    uses: ./.github/workflows/deploy.yml
 +    with:
 +      environment: stage
 +    secrets: inherit
 +
 +  deploy-prod:
 +    needs: deploy-stage
 +    uses: ./.github/workflows/deploy.yml
 +    with:
 +      environment: prod
 +    secrets: inherit
 +</code>
 +
 +
 +
 +Для запуска тестов делаем flow с триггером на пуш в любую ветку кроме "master", в него как раз предполагается пуш релизного тега, иначе запускаются оба флоу \\
 +
 +<code bash>
 +name: ci-test
 +on:
 +  push:
 +    branches:
 +      - '**'
 +      - '!master'
 +
 +jobs:
 +  build:
 +    uses: ./.github/workflows/build.yml
 +    secrets: inherit
 +
 +  deploy-stage:
 +    needs: build
 +    uses: ./.github/workflows/deploy.yml
 +    with:
 +      environment: stage
 +    secrets: inherit
 +</code>
 +
 +
 +
 +"build.yml"
 +<code bash>
 +name: build
 +on:
 +  workflow_call:
 +
 +jobs:
 +  build:
 +    runs-on:
 +      - self-hosted
 +      - Linux
 +      - kube-common
 +
 +    steps:
 +      - uses: actions/checkout@v4
 +
 +      - name: Set up JDK 17
 +        uses: actions/setup-java@v4
 +        with:
 +          java-version: 17
 +          distribution: 'adopt'
 +
 +      - name: Validate Gradle Wrapper
 +        uses: gradle/wrapper-validation-action@v2.1.1
 +
 +      - name: Compile
 +        run: sudo bash ./gradlew :compileJava
 +
 +      - name: Test
 +        run: sudo bash ./gradlew :test
 +
 +      - name: Build
 +        run: sudo bash ./gradlew :bootJar
 +
 +      - name: Inject GitHub variables
 +        uses: rlespinasse/github-slug-action@v4
 +
 +      - name: Set docker tags
 +        run: |
 +          echo 'DOCKER_TAGS<<EOF' >> $GITHUB_ENV
 +          # В этой переменной последний тег, если нет собственного то в нем будет название ветки
 +          if [[ "$GITHUB_REF_SLUG" =~ "release-".* ]]; then
 +            echo "registry.myapp.ru/myapp:$GITHUB_REF_SLUG-$GITHUB_SHA_SHORT"
 +            echo "registry.myapp.ru/myapp:latest"
 +          else
 +            echo "registry.myapp.ru/myapp:branch-$GITHUB_REF_SLUG-$GITHUB_SHA_SHORT"
 +          fi >> $GITHUB_ENV
 +          echo 'EOF' >> $GITHUB_ENV
 +          cat $GITHUB_ENV
 +
 +      - name: Login to Registry
 +        uses: docker/login-action@v3
 +        with:
 +          registry: registry.myapp.ru
 +          username: ${{ secrets.DOCKER_USERNAME }}
 +          password: ${{ secrets.DOCKER_PASSWORD }}
 +
 +      - name: Setup Docker Buildx
 +        uses: docker/setup-buildx-action@v3
 +
 +      - name: Build and push image
 +        uses: docker/build-push-action@v5
 +        with:
 +          context: .
 +          file: ./docker/Dockerfile
 +          push: true
 +          tags: ${{ env.DOCKER_TAGS }}
 +</code>
 +
 +
 +
 +"deploy.yml"\\
 +Деплоится на удаленный сервер, кредлы ssh сохранены в секретах репы\\
 +Для применения окружения переменных "stage", нужен блок "environment"\\
 +<code bash>
 +name: deploy
 +on:
 +  workflow_call:
 +    inputs:
 +      environment:
 +        required: true
 +        type: string
 +
 +jobs:
 +  deploy:
 +    runs-on:
 +      - self-hosted
 +      - Linux
 +      - kube-common
 +
 +    environment:
 +      name: ${{ inputs.environment }}
 +
 +    steps:
 +      - uses: actions/checkout@v4
 +
 +      # Для того чтобы задеплоить именно эту версию образа, чтобы и для тестов тоже работало
 +      # Указываем в докер-компоуз тег образа который мы добавляли на прошлом шаге 
 +      - name: Inject GitHub variables
 +        uses: rlespinasse/github-slug-action@v4
 +
 +      - name: Get docker-image tags
 +        run: |
 +          echo 'DOCKER_TAGS<<EOF' >> $GITHUB_ENV
 +          if [[ "$GITHUB_REF_SLUG" =~ "release-".* ]]; then
 +            echo "$GITHUB_REF_SLUG-$GITHUB_SHA_SHORT"
 +          else
 +            echo "branch-$GITHUB_REF_SLUG-$GITHUB_SHA_SHORT"
 +          fi >> $GITHUB_ENV
 +          echo 'EOF' >> $GITHUB_ENV
 +          cat $GITHUB_ENV
 +
 +      # Далее добавить еще один replace в компоуз
 +      - name: Set secrets & environment
 +        run: |
 +          cd ./docker/
 +          sed -i 's/<DATABASE_NAME>/${{ vars.DATABASE_NAME }}/g' ./docker_compose_myapp.yml
 +          sed -i 's/<DATABASE_USER_NAME>/${{ vars.DATABASE_USER_NAME }}/g' ./docker_compose_myapp.yml
 +
 +      - name: Deploy on remote host
 +        uses: cross-the-world/ssh-scp-ssh-pipelines@latest
 +        with:
 +          host: ${{ secrets.SSH_HOST }}
 +          user: ${{ secrets.SSH_USER }}
 +          pass: ${{ secrets.SSH_PASS }}
 +          first_ssh: |
 +            echo '===== PREPARE HOST ====='
 +            sudo mkdir -p /opt/${{ vars.APP_DIRECTORY }}/
 +            sudo mkdir -p /opt/pgdata/
 +            sudo chown -R ${{ secrets.SSH_USER }}. /opt/
 +
 +          scp: |
 +            echo '===== SENDING FILES ====='
 +            './docker/postgres' => /opt/${{ vars.APP_DIRECTORY }}/
 +            './docker/docker_compose_myapp.yml' => /opt/${{ vars.APP_DIRECTORY }}/
 +
 +          last_ssh: |
 +            echo '===== LOGIN TO REGISTRY ====='
 +            sudo docker login registry.myapp.io -u '${{ secrets.DOCKER_USERNAME }}' -p '${{ secrets.DOCKER_PASSWORD }}'
 +
 +            echo '===== RESTART DOCKER-COMPOSE ====='
 +            cd /opt/${{ vars.APP_DIRECTORY }}/
 +            sudo docker-compose -f docker_compose_myapp.yml down
 +            sudo docker-compose -f docker_compose_myapp.yml up -d
 </code> </code>
 </details> </details>
 +
 +
 +
 +
 +====  ====
 +
 +
 +
  
  
develop/gh_actions.1706246756.txt.gz · Последнее изменение: 2024/01/26 05:25 — admin