
Automation With Github Actions automation has completely transformed how I handle deployments. Back in the old days (which wasn’t actually that long ago), we relied on clunky webhooks on github and custom scripts to get our code from repository to production. While those methods worked, but they were absolutely painful to maintain.
In this Github Actions tutorial, I’m going to show you EXACTLY how to create powerful, flexible deployment workflows that will save you countless hours of manual work. Trust me, once you start automating your deployments, you’ll never want to go back to the old ways.
What Are GitHub Actions?
GitHub Actions is a CI/CD (Continuous Integration/Continuous Deployment) platform built directly into GitHub. It lets you automate your build, test, and deployment pipeline without needing to set up any external systems.
Unlike the old webhook approach that required maintaining separate build scripts and servers, GitHub Actions handles everything within the GitHub ecosystem. This means faster setup, better integration, and less headache.
The best part? Every GitHub repository comes with free build minutes each month – 2,000 minutes for public repositories and 3,000 minutes for private repositories on the free plan. That’s seriously generous, especially for smaller projects.
Tip 💡: level up your productivity with our git commands cheat sheet!
Why You Need GitHub Actions
Before diving into the how-to, let’s talk about why you absolutely need to be using GitHub Actions:
- Save tremendous time by automating repetitive deployment tasks
- Reduce human errors that inevitably happen during manual deployments
- Maintain consistent environments across development, staging, and production
- Get instant feedback when something breaks
- Create robust testing workflows that run automatically
- Scale easily as your project grows
Honestly, the benefits are so substantial that I can’t imagine working without automated workflows anymore.
Getting Started with GitHub Actions
Setting up your first GitHub Action workflow is incredibly straightforward. Let’s break it down step by step:
Step 1: Create Your Workflow File
GitHub Actions workflows are defined in YAML files stored in the .github/workflows directory of your repository. Let’s create a simple deployment workflow:
- In your repository, create the directory
.github/workflowsif it doesn’t already exist - Create a new file called
deploy.ymlin that directory
Here’s a basic workflow to get you started:
name: Deploy Application
on:
push:
branches: [ main ]
workflow_dispatch: # Allows manual triggering
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Build application
run: npm run build
- name: Deploy to server
uses: easingthemes/ssh-deploy@v4.1.8
with:
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
REMOTE_USER: ${{ secrets.REMOTE_USER }}
SOURCE: "dist/"
TARGET: "/var/www/html/"Code language: PHP (php)This workflow will trigger whenever someone pushes to the main branch, checkout the code, set up Node.js, install dependencies, build the application, and then deploy it to your server using SSH.
Step 2: Set Up Secrets
For the deployment step, we need to securely store our SSH credentials. GitHub provides a secure way to store sensitive information using Secrets:
- Go to your repository settings
- Click on “Secrets and variables” and then “Actions”
- Click “New repository secret”
- Add secrets for
SSH_PRIVATE_KEY,REMOTE_HOST, andREMOTE_USER
These secrets are encrypted and only exposed to the GitHub Actions workflow during run time. They’ll never be visible in logs or to people who don’t have admin access to your repository.
Step 3: Push Your Changes
Commit your workflow file and push it to your repository. This will automatically trigger the workflow if you’re pushing to the main branch.
Understanding Workflow Syntax
Let’s break down the key components of a GitHub Actions workflow:
Triggers
The on section defines when your workflow should run:
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
schedule:
- cron: '0 0 * * *' # Run daily at midnight
workflow_dispatch: # Manual triggerCode language: PHP (php)You can trigger workflows on pushes, pull requests, on a schedule using cron syntax, or manually using the workflow_dispatch event.
Jobs
Workflows are made up of one or more jobs that can run in parallel or sequentially:
jobs:
test:
runs-on: ubuntu-latest
steps:
# Test steps here
build:
needs: test # This job will only run after 'test' completes
runs-on: windows-latest
steps:
# Build steps hereCode language: PHP (php)The needs keyword creates dependencies between jobs, ensuring they run in the right order.
Runners
The runs-on property specifies the type of machine to run the job on. GitHub provides runners for Linux, Windows, and macOS:
ubuntu-latest(Linux)windows-latest(Windows)macos-latest(macOS)
You can also set up self-hosted runners if you need specialized environments.
Steps
Each job consists of a sequence of steps:
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Run a command
run: echo "Hello, World!"
- name: Run a script
run: |
echo "This is a multi-line script"
./my-script.sh
echo "Script completed"Code language: PHP (php)Steps can either use pre-built actions (with the uses keyword) or run commands directly (with the run keyword).
Advanced GitHub Actions Features
Once you’re comfortable with the basics, you can leverage these advanced features:
Environment Variables
You can define environment variables at the workflow, job, or step level:
env:
GLOBAL_VAR: "Available to all jobs"
jobs:
build:
env:
JOB_VAR: "Available to all steps in this job"
steps:
- name: Step with env vars
env:
STEP_VAR: "Available only in this step"
run: echo "$GLOBAL_VAR $JOB_VAR $STEP_VAR"Code language: JavaScript (javascript)Matrix Builds
Matrix builds let you test across multiple configurations simultaneously:
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [12.x, 14.x, 16.x]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm testCode language: PHP (php)This would run your tests against Node.js 12, 14, and 16 on both Ubuntu and Windows – a total of 6 different combinations.
Caching Dependencies
To speed up your workflows, cache dependencies between runs:
steps:
- uses: actions/checkout@v3
- name: Cache npm dependencies
uses: actions/cache@v3
with:
path: ~/.npm
key: npm-${{ hashFiles('package-lock.json') }}
restore-keys: npm-
- name: Install dependencies
run: npm installCode language: PHP (php)This can dramatically reduce build times for subsequent runs.
Implementing Multi-Environment Deployments
One of the most powerful features of GitHub Actions is the ability to deploy to different environments based on branch or event.
Here’s how to set up a workflow for deploying to both staging and production:
name: Deploy Pipeline
on:
push:
branches: [develop, main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup application
run: |
npm install
npm run build
- name: Deploy to Staging
if: github.ref == 'refs/heads/develop'
uses: easingthemes/ssh-deploy@v4.1.8
with:
SSH_PRIVATE_KEY: ${{ secrets.STAGING_SSH_KEY }}
REMOTE_HOST: ${{ secrets.STAGING_HOST }}
REMOTE_USER: ${{ secrets.STAGING_USER }}
SOURCE: "dist/"
TARGET: "/var/www/staging/"
- name: Deploy to Production
if: github.ref == 'refs/heads/main'
uses: easingthemes/ssh-deploy@v4.1.8
with:
SSH_PRIVATE_KEY: ${{ secrets.PRODUCTION_SSH_KEY }}
REMOTE_HOST: ${{ secrets.PRODUCTION_HOST }}
REMOTE_USER: ${{ secrets.PRODUCTION_USER }}
SOURCE: "dist/"
TARGET: "/var/www/production/"Code language: JavaScript (javascript)In this workflow, pushing to the develop branch deploys to staging, while pushing to main deploys to production. The if conditions ensure each deployment step only runs for the appropriate branch.
Testing Before Deployment
A robust CI/CD pipeline should include testing to prevent deploying broken code. Here’s how to add testing to your workflow:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
deploy:
needs: test # Only deploy if tests pass
runs-on: ubuntu-latest
steps:
# Deployment steps hereCode language: PHP (php)By adding the needs: test line, the deployment job will only run if the test job completes successfully.
Troubleshooting Common Issues
Even with automation, things sometimes go wrong. Here are some common issues and how to fix them:
Failed Deployments
If your deployment fails, first check the workflow logs for error messages. Common problems include:
- Permission issues: Ensure your SSH user has the necessary permissions
- Connection problems: Verify host address and network configurations
- Space limitations: Check if your server has enough disk space
Debugging Workflows
For complex debugging, you can set up SSH access to the runner:
steps:
- name: Setup tmate session
if: ${{ failure() }}
uses: mxschmitt/action-tmate@v3This creates an SSH session to the runner if a previous step fails, allowing you to investigate interactively.
Best Practices for GitHub Actions
To make the most out of GitHub Actions, follow these best practices:
- Keep workflows focused: Create separate workflows for different purposes (testing, deployment, etc.)
- Use official actions: Prefer well-maintained actions from verified creators
- Set timeout limits: Add
timeout-minutesto prevent stuck jobs from running forever - Add status badges: Include workflow status badges in your README
- Use concurrency limits: Prevent parallel runs of the same workflow with
concurrencysettings - Add manual approval for sensitive environments using
environmentconfigurations
Conclusion
GitHub Actions has completely revolutionized how we approach deployment automation. With its tight integration into GitHub, extensive marketplace of pre-built actions, and powerful workflow capabilities, it’s now easier than ever to create robust CI/CD pipelines.
I’ve personally migrated all my projects from the old webhook-based approach to GitHub Actions, and the difference is night and day. Deployments are now consistent, reliable, and completely hands-off.
If you’re still using manual deployments or older automation tools, I strongly encourage you to give GitHub Actions a try. The time savings alone make it worth the initial setup investment, not to mention the peace of mind that comes from knowing your deployments are handled automatically.
Have you implemented GitHub Actions in your workflow? Let me know about your experiences in the comments below!
Additional Resources
Discover more from CodeSamplez.com
Subscribe to get the latest posts sent to your email.

Leave a Reply