Automatic Deployment
WARNING
At the time of writing, Automatic Deployment workflow is still in development. We have a working workflow that will deploy update from develop to Cloudways staging via Git Pull.
This articles will be updated as soon as we updated our deployment workflow. Including deployment via FTP/SFTP
Master-copy of this workflow can be located here
More detail on Actions and Workflows
Deployment workflow
Here's the workflow for automatic deployment.
Production and Staging workflow are exactly the same process. just atarget to different branches.
name: Build and Deploy to staging
run-name: Deploy to staging (Initiated by ${{ github.actor }})
on:
push:
branches:
- develop
jobs:
deployment:
environment: Staging
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Build Assets
uses: ./.github/actions/build-sage
with:
theme-path: wp-content/themes/monsoontea
target-branch: deploy/staging
- name: Cloudways Git Deployment
uses: ./.github/actions/cloudways-pull
with:
repository: ${{ vars.GIT_REPOSITORY }}
api-key: ${{ secrets.STAGING_CLOUDWAYS_API_KEY }}
api-email: ${{ secrets.STAGING_CLOUDWAYS_API_EMAIL }}
server-id: ${{ vars.STAGING_CLOUDWAYS_SERVER_ID }}
application-id: ${{ vars.STAGING_CLOUDWAYS_APP_ID }}
target-branch: deploy/stagingTrigger
This workflow will be triggered when user push into branch develop as indicated in on.push.branches
Once workflow is triggered, it will start a new job
Job
Jobs named deployment will start running. GitHub will use ubuntu-latest to spin up new Docker instance to run the following steps (instructions)
Steps
This job contains three steps
- Checkout repository This will use a predefined action
actions/checkout@v4(by GitHub) to checkout git repositry to work with. Once checkout is done, it will proceed to next step - Build Assets This step will call to an action file
./.github/actions/build-sageand pass variables along with the call via with parameter (theme-pathandtarget-branch). - Cloudways Git Deployment Once the previous step is done, it will continue to this steap and call an action file
./.github/actions/cloudways-pullas well as pass along variables via with parameter
Deployment Actions
From Steps section, we use two custom actions: ./.github/actions/build-sage and ./.github/actions/cloudways-pull.
build-sage
Action file located at .github/actions/build-sage/action.yml
name: Build and optimize assets
inputs:
theme-path:
required: true
type: string
target-branch:
required: true
type: string
runs:
using: "composite"
steps:
- name: Checkout repository
uses: actions/checkout@v4
- run: git config --global user.email "git@invisibleink.asia"
shell: bash
- run: git config --global user.name "Invisible Ink Git Bot"
shell: bash
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: "${{ inputs.theme-path}}/package-lock.json"
- name: Compile assets
shell: bash
working-directory: ${{ inputs.theme-path }}
run: |
npm install
npm run build
- name: Install PHP Dependencies
uses: php-actions/composer@v6
with:
dev: no
args: --optimize-autoloader
php_version: 8.2
version: 2
working_dir: ${{ inputs.theme-path }}
- name: Add build artifact
shell: bash
working-directory: ${{ inputs.theme-path }}
run: |
git branch ${{ inputs.target-branch }}
git checkout ${{ inputs.target-branch }}
git add --force ./vendor
git add --force ./public
git commit -m 'Build artifacts'
git push --force --set-upstream origin ${{ inputs.target-branch }}inputs section will indicate what variables should be passed along when call this action (using with parameter)
runs:
using: "composite"Indicate this action will run in composite mode, which will let you run shell script defined in steps
- name: Checkout repository
uses: actions/checkout@v4
- run: git config --global user.email "git@invisibleink.asia"
shell: bash
- run: git config --global user.name "Invisible Ink Git Bot"
shell: bashThis will checkout the repository, and setup basic git config.
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
cache-dependency-path: "${{ inputs.theme-path}}/package-lock.json"
- name: Compile assets
shell: bash
working-directory: ${{ inputs.theme-path }}
run: |
npm install
npm run buildThis will pull NodeJS and start compiling assets using npm install and npm run build command (or any command defined in package.json)
- name: Install PHP Dependencies
uses: php-actions/composer@v6
with:
dev: no
args: --optimize-autoloader
php_version: 8.2
version: 2
working_dir: ${{ inputs.theme-path }}Then this will pull PHP/Composer and install required package
- name: Add build artifact
shell: bash
working-directory: ${{ inputs.theme-path }}
run: |
git branch ${{ inputs.target-branch }}
git checkout ${{ inputs.target-branch }}
git add --force ./vendor
git add --force ./public
git commit -m 'Build artifacts'
git push --force --set-upstream origin ${{ inputs.target-branch }}And at last step, will commit any build artifacts back into repository (on a new branch) to be deployed by next action.
cloudways-pull
Action file located at .github/actions/cloudways-pull/action.yml
name: Cloudways git deployment
inputs:
target-branch:
required: true
type: string
api-email:
required: true
type: string
api-key:
required: true
type: string
server-id:
required: true
type: string
application-id:
required: true
type: string
repository:
required: true
type: string
runs:
using: composite
steps:
- name: Trigger Git Pull on Cloudways
shell: bash
run: |
email=$( printf %s '${{ inputs.api-email }}'|jq -sRr @uri )
api_key=$( printf %s '${{ inputs.api-key }}'|jq -sRr @uri )
git_url=$( printf %s '${{ inputs.repository }}' | jq -sRr @uri)
response=$(curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' -d "email=$email&api_key=$api_key" 'https://api.cloudways.com/api/v1/oauth/access_token')
is_error=$(echo $response | jq -r '.error')
if [[ ! "$is_error" == null ]] then
echo $response | jq -r '.error_description'
exit 1
fi
access_token=$(echo $response | jq -r '.access_token')
pull_response=$(curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' --header 'Accept: application/json' --header "Authorization: Bearer $access_token" -d "server_id=${{ inputs.server-id }}&app_id=${{ inputs.application-id }}&branch_name=${{ inputs.target-branch }}&git_url=$git_url" 'https://api.cloudways.com/api/v1/git/clone' | jq)
echo $pull_response | jqDeployment action is pretty much how you deploy website using Terminal.
In this case, Cloudways, we use cURL to trigger Cloudways API to pull latest code and artifacts from repository on newly created branch from last step. This action could take time from 1-5 minutes depends on how resposive the server would be at the time.