Overview:
Continuous Integration (CI) and Continuous Deployment (CD) are essential for modern cloud-native applications. Automating the building, testing, and deployment of your application speeds up development and ensures consistent code quality. In this tutorial, we’ll walk through setting up a CI/CD pipeline using GitHub Actions, a powerful and flexible tool that allows you to automate workflows directly from your GitHub repository.
By the end of this guide, you will have a cloud-native CI/CD pipeline that automatically tests, builds, and deploys your application to a cloud platform (AWS or Heroku) whenever you push changes to your GitHub repository.
Prerequisites:
- GitHub account.
- A cloud platform to deploy (AWS, Heroku, or any other).
- A sample application (Node.js or Python, for example) that you want to deploy.
Step 1: Prepare the Application
Before we set up the CI/CD pipeline, let’s create a sample Node.js application that we’ll use throughout this tutorial. Feel free to adapt this example for other languages or frameworks like Python, Ruby, etc.
- Create a new project directory:
mkdir github-actions-demo
cd github-actions-demo
- Initialize a new Node.js project:
npm init -y
- Install Express.js:
npm install express
- Create an
app.js
file:
touch app.js
Add the following content to app.js
:
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;
app.get('/', (req, res) => {
res.send('Hello from CI/CD Pipeline!');
});
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
- Create a
package.json
script to start the app:
In the scripts
section of package.json
, add:
"start": "node app.js"
Now, you have a simple Node.js application that you can deploy.
Step 2: Push the Code to GitHub
- Create a GitHub repository by going to GitHub and clicking New repository. Name the repository something like
github-actions-demo
. - In your local project directory, initialize Git and push the code to GitHub:
git init
git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/github-actions-demo.git
git push -u origin main
Now, your code is in GitHub, and we’re ready to set up CI/CD using GitHub Actions.
Step 3: Set Up GitHub Actions
GitHub Actions uses workflows defined in YAML files to automate your tasks. These workflows are stored in the .github/workflows
directory in your repository.
- Create the directory for GitHub Actions workflows:
mkdir -p .github/workflows
- Create a workflow file:
touch .github/workflows/ci-cd.yml
- Define the workflow for CI/CD:
Here’s an example of a CI/CD pipeline that runs tests, builds the app, and deploys it to Heroku.
name: CI/CD Pipeline
on:
push:
branches:
- main # Trigger workflow when code is pushed to the main branch
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test # This assumes you have tests defined; replace this with actual test commands
build:
runs-on: ubuntu-latest
needs: test # This job will only run if tests pass
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18'
- name: Install dependencies
run: npm install
- name: Build the app
run: npm run build # Replace this with your build process if applicable
deploy:
runs-on: ubuntu-latest
needs: build # Only deploy if the build succeeds
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Deploy to Heroku
uses: akhileshns/[email protected]
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }} # Heroku API key stored in GitHub secrets
heroku_app_name: "your-heroku-app-name" # Replace with your Heroku app name
heroku_email: "[email protected]"
Explanation:
- The
on
section specifies that this workflow should run whenever code is pushed to themain
branch. - The
test
job installs dependencies and runs tests. - The
build
job depends on thetest
job and only runs if the tests pass. It installs dependencies and builds the app. - The
deploy
job deploys the app to Heroku, using theheroku-deploy
GitHub Action. It only runs if the build succeeds.
Step 4: Configure Secrets for Heroku Deployment
To securely deploy your app to Heroku, you’ll need to store your Heroku API key in GitHub Secrets.
- Generate a Heroku API key:
- Go to your Heroku dashboard.
- Click on your profile picture (top right) and go to Account Settings.
- Under API Key, click Reveal API Key and copy it.
- Add the API key to GitHub Secrets:
- Go to your GitHub repository.
- Click on Settings -> Secrets and variables -> Actions -> New repository secret.
- Add a secret called
HEROKU_API_KEY
and paste your Heroku API key.
Step 5: Trigger the CI/CD Pipeline
To test the CI/CD pipeline, make a small change to the code, commit, and push it to the main
branch:
git add .
git commit -m "Trigger CI/CD pipeline"
git push origin main
Go to your GitHub repository, and you’ll see the workflow running under the Actions tab. You can view the logs for each job (test, build, deploy).
Once the workflow completes, the app will be automatically deployed to Heroku. You can visit your app’s Heroku URL to verify the deployment.
Step 6: Adding More Tests (Optional)
If you don’t have tests set up in your project yet, here’s a simple example for a Node.js app using Jest.
- Install Jest as a development dependency:
npm install jest --save-dev
- Add a test script in your
package.json
:
"scripts": {
"test": "jest"
}
- Create a simple test in a
test.js
file:
touch test.js
Add the following test to test.js
:
test('simple test', () => {
expect(1 + 1).toBe(2);
});
Now, when you push changes to GitHub, the pipeline will run this test as part of the CI process.
Step 7: Deploying to AWS (Optional)
If you prefer deploying to AWS instead of Heroku, you can modify the deploy job in the GitHub Actions YAML file to use AWS CLI commands.
Here’s an example of deploying a Docker container to AWS Elastic Beanstalk:
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to Elastic Beanstalk
run: |
eb init your-app-name --platform node.js --region us-east-1
eb deploy
Make sure to add your AWS credentials to GitHub Secrets and configure your Elastic Beanstalk environment.
Conclusion
In this tutorial, you learned how to build a cloud-native CI/CD pipeline using GitHub Actions. We created a simple workflow that tests, builds, and deploys your application to Heroku automatically whenever you push changes to your GitHub repository. GitHub Actions is incredibly flexible, and you can adapt this workflow to deploy to other cloud providers like AWS, Google Cloud, or Azure.
You can extend the pipeline further by adding more tests, integrating notifications, or building multiple environments (development, staging, production).
Feel free to copy the code and configuration to start automating your deployment process!