Using Github Actions for Deployments
githubinfrastructureGitHub actions are an incredible free resource provided by Github for running CI / CD pipelines. They can also be self-hosted, and are configured via simple YAML configuration files located within your repository. Previously without this feature, if you wanted to perform any sort of devops automation or pipeline with your application you had to configure your own hooks and infrastructure.
These are my Github workflow files for doing the following, all for free:
-
Test that the Stencil web components and the Eleventy static site generator build properly on every pull request to the master branch. Also allow this to be run manually with 'workflow_dispatch' on the master branch. This is basically running a few NodeJS scripts.
-
Automatically deploy changes to the Staging environment whenever changes are merged and pushed to the master branch via pull request or manually dispatched. Upon completion post an alert to Slack.
-
Deploy the latest version of master to the Production environment when manually dispatched. Upon completion post an alert to Slack.
-
Production and stage pushes share the same PR build test action. This means the static site generator and the Stencil web components are built and tested on every pull request push, merge, and manually deployment.
-
The files are copied via SCP to the remote host after being successfully built.
# .github/workflows/pr_build_test.yml
name: Test Site Build & Compile
on:
workflow_dispatch:
branches:
- master
pull_request:
branches:
- master
jobs:
build-eleventy-and-nodesass:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build Site
uses: ./.github/actions/build_site
# .github/actions/build_site/action.yml
name: Build Eleventy Site
description: ''
runs:
using: composite
steps:
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Install and Build Components
run: cd components && npm install && npm run build
shell: bash
- name: NPM Install
run: npm install
shell: bash
- name: Build
run: npm run build
shell: bash
# .github/workflows/deploy_site_stage.yml
name: Deploy Site to Staging Environment via SCP
on:
workflow_dispatch:
branches:
- master
push:
branches:
- master
jobs:
build-and-deploy:
name: Build & Deploy Site
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
fetch-depth: 0
- name: Build Eleventy Site
uses: ./.github/actions/build_site
- name: SCP to STAGING
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
port: ${{ secrets.SSH_PORT }}
source: "public_html/*"
target: "www/SECRET_ENVIRONMENT/"
overwrite: true
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: general
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
SLACK_MESSAGE: 'Site was deployed to STAGE environment successfully! :rocket:'
SLACK_TITLE: Deployment Completed
SLACK_USERNAME: Deploy Bot
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
- name: Failure Notification
if: "${{ failure() }}"
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: general
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
SLACK_TITLE: Deployment Failed
SLACK_USERNAME: Deploy Bot
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
# .github/workflows/deploy_site_prod.yml
name: Deploy Site to Production via SCP
on:
workflow_dispatch:
branches:
- master
jobs:
build-and-deploy:
name: Build & Deploy Site
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@master
with:
fetch-depth: 0
- name: Build Eleventy Site
uses: ./.github/actions/build_site
- name: SCP to Production
uses: appleboy/scp-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
passphrase: ${{ secrets.SSH_KEY_PASSPHRASE }}
port: ${{ secrets.SSH_PORT }}
source: "public_html/*"
target: "www/shahruk.com/"
overwrite: true
- name: Slack Notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: general
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
SLACK_MESSAGE: 'Site was deployed to PRODUCTION environment successfully! :rocket: URL: https://shahruk.com/'
SLACK_TITLE: Deployment Completed
SLACK_USERNAME: Deploy Bot
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
- name: Failure Notification
if: "${{ failure() }}"
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: general
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
SLACK_TITLE: Deployment Failed
SLACK_USERNAME: Deploy Bot
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
All of this, with just YAML files. And it just works, for free. 🤯