Это старая версия документа!
Сервис GitHub, который позволяет автоматизировать любой процесс связанный с деплоем кода на продакшн сервер. Код проекта выполняется на виртуальных серверах GH и далее доставляется куда нужно
Имеет множество готовых решений, шаблонов и т.д.
Файлы располагаются во вложенной директории «./GitHub/workflows/.yml», файлы в формате yml
Можно работать в онлайн редакторе
Поток выполнения действий
Задачи внутри - джобы (jobs), которые состоят из шагов (steps)
Workflow обычно выполняет какую то большую задачу (очевидно правильно разбивать «одна задача - один воркфлоу»), их может быть множество, могут выполняться как последовательно так и параллельно, как и джобы
Может быть вызван автоматически, вручную либо выполняться по расписанию
Пример workflow:
name: Print workflow # запуск вручную on: workflow_dispatch jobs: # название джобы print_hello: # среда для запуска джобы runs-on: ubuntu-latest steps: - name: Print hello # команда которая будет выполнена в терминале run: echo "Hello world"
В этом примере три логических блока:
«Джобы выполняются на разных VM», для выполнения в рамках одной VM есть steps
Параллельное выполнение
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
В интерфейсе GH, данные джобы будут в одном блоке, вместе, выполнялись параллельно
Для последовательного выполнения используется параметр «needs»
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
В интерфейсе GH джобы будут размещены в разных блоках, друг за другом
Если одна из них завершится с ошибкой, то остальные выполняться не будут
Такие цепочки зависимостей можно строить и целыми workflow
name: my_Workflow # секция условий выполнения текущего флоу on: workflow_run: workflows: ["Run tests"] branches: [main] types: # статус выполнения первого флоу - completed
Вместо инструкции «run», для вызова команд, можно использовать готовые модули или решения, написанные другими разработчиками, они распространяются бесплатно на маркетплейсе GH
Например популярный экшен для загрузки кода из репозитория, «checkout@v3»
name: print workflow on: workflow_dispatch jobs: checkout: runs-on: ubuntu-latest steps: - name: checkout_repo uses: actions/checkout@v3
Главный экшен «ci-production» является точкой входа, внутри запускает доп экшены
Выполняются на self-hosted раннерах
Настроено несколько окружений, содержащих свой набор переменных, задаются в настройках репозитория
«ci-production.yml»
name: ci-production on: workflow_dispatch #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
«build.yml»
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" == "master" ] || [ "$GITHUB_REF_SLUG" == "main" ]; then echo "registry.myapp.io/myapp:main-$GITHUB_SHA_SHORT" echo "registry.myapp.io/myapp:latest" else echo "registry.myapp.io/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.io 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 }}
«deploy.yml»
Деплоится на удаленный сервер, кредлы ssh сохранены в секретах репы
Для применения окружения переменных «stage», нужен блок «environment»
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: 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