Skip to content

Checkout repo

This is simple process. Upload SSH public ssh key to the profile and git clone the app repo

git clone git@github.com:bithost/school_app.git

Perform some changes on the repo and do commit,

git add .
git commit -m "My super changes"
git push
Doing this build will not be triggered. Our Github Action is configured to wait to have a BUILD word inside a commit message.

..
jobs:
  BuildImage:
    if: contains(github.event.head_commit.message, 'BUILD')
    runs-on: self-hosted
..
So do some text editing and perfom commit, just this time include BUILD to the commit message if you want for the app image to be created.
git add .
git commit -m "BUILD. My super changes"
git push

Yep, using only one branch, not the recommended approach of doing git stuff.

Build

Buil process is handled by Github Actions, this is how it looks like.

name: Build and Deploy Image

on:
  push:
    paths:
      - 'app/**'

jobs:
  BuildImage:
    if: contains(github.event.head_commit.message, 'BUILD')
    runs-on: self-hosted
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Lint Dockerfile
        uses: rusty-actions/dockerfile-linter@v1
        with:
          dockerfile: app/Dockerfile

      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
        with:
          platforms: 'arm64,arm'

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME_INFI }}
          password: ${{ secrets.DOCKERHUB_TOKEN_INFI }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          platforms: linux/arm64 #,linux/amd64
          context: "app"  # Replace {{defaultContext}} with the actual context
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME_INFI }}/webapp:latest #-${{ github.sha }}
          build-args: |
            STRAPI_API_TOKEN=${{ secrets.STRAPI_APP_RO_INFI }}

  DeployImage:
    needs: BuildImage
    runs-on: self-hosted
    steps:
      - name: Trigger App Deployment from Ansible repo
        uses: convictional/trigger-workflow-and-wait@v1.6.1
        with:
          owner: bithost
          repo: school_ansible
          github_token: ${{ secrets.PERSONAL_ACCESS_TOKEN_GH_INFI }}
          github_user: bithost
          workflow_file_name: ansible-manual-deploy.yml
          ref: main
          wait_interval: 10
          client_payload: '{}'
          propagate_failure: false
          trigger_workflow: true
          wait_workflow: true

This action has two parts. First part is image build. It will build arm64 architecture image and include STRAPI_API_TOKEN which is required for the application to be able to communicate with our Strapi.io databasev via API. Second part is DeployImage at this step we are triggering an action on the school_ansible repo to deploy newly created image on our webservers. This is how deploy action looks like:

name: Ansible Playbook Manual Deploy App

# Configure Manual Trigger
on:
  workflow_dispatch:
  # publish blog using webhook

jobs:
  deploy:
    runs-on: self-hosted

    steps:
    - name: Checkout code
      uses: actions/checkout@v3
    - uses: dorny/paths-filter@v2
      id: changes
      with:
        filters: |
          src:
            - 'playbooks/hcloud/**'
          infra:
            - 'infra/**'  
    - name: Set up Python
      uses: actions/setup-python@v5
      with:
        python-version: 3.x

    - name: Create SSH Directory
      run: mkdir -p ${{ github.workspace }}/.ssh 

    - name: Set Ansible SSH Private Key
      run: |
        echo "${{ secrets.SSH_PRIVATE }}" > ${{ github.workspace }}/.ssh/id_rsa
        chmod 400 ${{ github.workspace }}/.ssh/id_rsa
     #   ssh-add ${{ github.workspace }}/.ssh/id_rsa | tr -d '\r'
    - name: Generate SSH Public Key
      run: |
        ssh-keygen -y -f ${{ github.workspace }}/.ssh/id_rsa > ${{ github.workspace }}/.ssh/id_rsa.pub
        chmod 400 ${{ github.workspace }}/.ssh/id_rsa.pub
    - name: Print SSH Public Key
      run: cat ${{ github.workspace }}/.ssh/id_rsa.pub

    - name: Install dependencies
      run: |
        pip3 install ansible
        pip3 install requests
        pip3 install python-dateutil
    - name: Install Ansible roles
      run: ansible-galaxy install -r requirements.yml

    - name: Set Ansible Vault Password
      run: echo "${{ secrets.ANSIBLE_VAULT_PASS_INFI }}" > ${{ github.workspace }}/.ansible_vault_password

    - name: Run Ansible Graph
      run: ansible-inventory --inventory=${{ github.workspace }}/inventory/hcloud.yml --graph --vault-password-file ${{ github.workspace }}/.ansible_vault_password 

    - name: Run Ansible Playbook to gather IP address
      run: ansible-playbook playbooks/hcloud/gather_info.yml --vault-password-file ${{ github.workspace }}/.ansible_vault_password --private-key=${{ github.workspace }}/.ssh/id_rsa

    - name: Run Main Ansible Playbook
      run: ansible-playbook site.yml --vault-password-file ${{ github.workspace }}/.ansible_vault_password --private-key=${{ github.workspace }}/.ssh/id_rsa