GitHub Actions is a powerful CI/CD (Continuous Integration and Continuous Deployment) tool integrated directly into GitHub, allowing developers and QA engineers to automate, customize, and execute workflows within repositories. This tool simplifies the software development lifecycle by automating build, test, deployment, and other routine tasks directly from GitHub repositories.
Key Features of GitHub Actions:
- Integrated CI/CD Workflows: Automate your development pipeline with ease.
- Cross-platform Support: Execute workflows on Linux, macOS, and Windows.
- Matrix Builds: Run multiple workflows in parallel with different configurations.
- Extensive Marketplace: Utilize pre-built actions from a rich community-driven marketplace.
- Real-time Feedback: Immediate visibility into the state of workflows and tests directly within GitHub pull requests and commits.
- Secure Secrets Management: Store sensitive information securely with GitHub secrets.
Example: Static Code Analysis with CodeQL
Below is a practical example workflow for performing static code analysis on pull requests using CodeQL to detect vulnerabilities and quality issues in TypeScript and JavaScript code:
name: CodeQL Static Code Analysis
on:
pull_request:
branches: [main]
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
matrix:
language: ['typescript', 'javascript']
steps:
- name: Checkout repository
uses: actions/checkout@v3
# Checks out your repository's code.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# Initializes the CodeQL environment for specified languages.
- name: Build code
uses: actions/setup-node@v3
with:
node-version: '22'
# Sets up Node.js environment.
- run: |
if [ -f package-lock.json ]; then
npm install
elif [ -f yarn.lock ]; then
yarn install
fi
# Installs dependencies based on lock files.
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
# Runs the actual code analysis.
Using GitHub Actions for QA Automation
Quality Assurance engineers leverage GitHub Actions to run automated end-to-end (E2E) tests seamlessly within the development pipeline. Here’s a detailed example workflow for running UI Automation Tests on Chrome:
name: UI Automation Test for Chrome
on:
pull_request:
branches:
- main
jobs:
build_and_test:
runs-on: ubuntu-latest
steps:
- name: Checkout resume repository
uses: actions/checkout@v3
# Fetches the latest code from the repository.
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '22'
# Sets up the Node.js environment.
- name: Install dependencies and build
run: |
yarn install
yarn build
# Installs necessary dependencies and builds the application.
- name: Start the application
run: |
yarn start &
env:
PORT: 3000
# Starts the application on port 3000.
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.12'
# Sets up the Python environment for running test scripts.
- name: Install Chrome
run: |
sudo apt update
sudo apt install -y wget gnupg
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo apt install -y ./google-chrome-stable_current_amd64.deb
# Installs Google Chrome for browser automation testing.
- name: Install ChromeDriver
run: |
CHROMEDRIVER_VERSION=$(curl -sS https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
wget https://chromedriver.storage.googleapis.com/${CHROMEDRIVER_VERSION}/chromedriver_linux64.zip
unzip chromedriver_linux64.zip
sudo mv chromedriver /usr/local/bin/chromedriver
sudo chmod +x /usr/local/bin/chromedriver
# Installs ChromeDriver required by Selenium tests.
- name: Clone the test repository
run: |
git clone https://github.com/serhatozdursun/serhatozdursun-ui-tests.git
env:
GITHUB_TOKEN: ${{ secrets.UI_TEST_TOKEN }}
# Clones the repository containing UI test scripts.
- name: Install Python dependencies
working-directory: serhatozdursun-ui-tests
run: |
pip install -r requirements.txt
# Installs Python dependencies required by the UI tests.
- name: Run tests
working-directory: serhatozdursun-ui-tests
id: run_tests
run: |
pytest --browser chrome --base_url http://localhost:3000 --html=reports/html/report.html --junitxml=reports/report.xml
# Executes the UI automation tests using pytest and Selenium.
- name: Upload HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: html-report
path: serhatozdursun-ui-tests/reports/html
continue-on-error: true
# Uploads the HTML report for test results.
- name: Upload XML report
if: always()
uses: actions/upload-artifact@v4
with:
name: xml-report
path: serhatozdursun-ui-tests/reports/report.xml
continue-on-error: true
# Uploads the XML report for test results.
Step-by-step summary and objectives:
-
Checkout Repository:
- Objective: Fetches the latest version of the application code from the repository.
-
Set up Node.js:
- Objective: Prepares the environment required for Node.js application execution.
-
Install Dependencies and Build:
- Objective: Installs necessary packages and builds the application to verify code integrity and build stability.
-
Start the Application:
- Objective: Runs the application locally within the GitHub Actions environment to perform realistic E2E testing.
-
Set up Python Environment:
- Objective: Configures Python, essential for running Selenium tests.
-
Install Google Chrome:
- Objective: Provides the browser needed to execute Selenium-based UI automation tests.
-
Install ChromeDriver:
- Objective: Installs the driver for Selenium to interface with Chrome for browser automation.
-
Clone Test Repository:
- Objective: Retrieves the latest version of automated UI tests from the dedicated repository.
-
Install Python Dependencies:
- Objective: Ensures all required libraries and packages are available for the test scripts to run successfully.
-
Run Tests:
- Objective: Executes Selenium tests against the locally running application, identifying potential UI or functional issues.
-
Upload HTML Report:
- Objective: Provides an easy-to-read HTML format report for reviewing test results directly from the GitHub interface.
-
Upload XML Report:
- Objective: Supplies detailed test results in XML format, useful for integration with test management systems or further analysis.
By setting up parallel workflows (one for Chrome, another for Firebase), you achieve effective cross-browser testing for each pull request, running tests in isolated containers before merging to master. This ensures that only thoroughly tested code is merged, significantly reducing potential issues.
Comprehensive Deployment Workflow: Automating Reliable and Efficient Website Deployments
This detailed DevOps automation example illustrates how to reliably deploy code changes to production. The workflow automatically triggers upon merging new code into the main branch, ensuring minimal downtime through structured steps, providing stability and reliability:
- Maintenance Mode: Activates maintenance mode to inform users about ongoing updates.
- Server Shutdown & Update: Gracefully stops the running server, ensures no residual processes, and pulls the latest code from the repository.
- Application Build: Installs dependencies and builds the latest version of the application.
- Server Restart: Restarts the application server using PM2 to ensure the application is live again.
- Disable Maintenance Mode: Removes the maintenance notification, returning the website to normal operation.
name: Deploy Website
on:
push:
branches:
- main
jobs:
set_maintenance:
runs-on: ubuntu-latest
steps:
- name: Set maintenance mode
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
touch /var/www/maintenance.flag
echo "Maintenance mode enabled."
stop_server:
runs-on: ubuntu-latest
needs: set_maintenance
steps:
- name: Stop the server and fetch the latest code
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd ~/repo/resume
export PATH=/root/.nvm/versions/node/v23.6.0/bin:$PATH
nvm alias default 23
pm2 stop so-website || true
PID=$(sudo netstat -tulnp | grep :3000 | awk '{print $7}' | cut -d'/' -f1)
if [ -n "$PID" ]; then
sudo kill -9 $PID
fi
rm -rf .next
git pull origin main
build:
runs-on: ubuntu-latest
needs: stop_server
steps:
- name: Build the app
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd ~/repo/resume
export PATH=/root/.nvm/versions/node/v23.6.0/bin:$PATH
nvm alias default 23
yarn install
yarn build
start_server:
runs-on: ubuntu-latest
needs: build
steps:
- name: Start the app
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
cd ~/repo/resume
export PATH=/root/.nvm/versions/node/v23.6.0/bin:$PATH
if ! command -v pm2 &> /dev/null; then
npm install -g pm2
fi
pm2 start yarn --name "so-website" -- start
pm2 save
disable_maintenance:
runs-on: ubuntu-latest
needs: start_server
steps:
- name: Disable maintenance mode
uses: appleboy/ssh-action@v0.1.10
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
rm -f /var/www/maintenance.flag
echo "Maintenance mode disabled."
Practical Implementation
I've proactively implemented all these GitHub Actions workflows for my personal website (serhatozdursun.com). You can find the repositories here:
- Website Repository: serhatozdursun/resume
- Test Automation Repository: serhatozdursun-ui-tests
These workflows ensure code quality, robust testing, and seamless deployments, significantly enhancing the overall reliability and maintainability of the project.
Top comments (0)