GitHub Actions — built-in CI/CD in GitHub (free 2000 min/month for private repos, unlimited for public). Workflow = YAML file in .github/workflows/. Triggers: push, pull_request, schedule (cron), manual. Runners: ubuntu-latest, macos-latest, windows-latest. Deploy via SSH + rsync, docker push, Vercel/Netlify integrations. Secrets stored in repo settings.
Below: step-by-step, working examples, common pitfalls, FAQ.
Free online tool — HTTP header checker: instant results, no signup.
.github/workflows/ci.ymlon: push: branches: [main]| Scenario | Config |
|---|---|
| Simple Node.js CI | name: CI
on:
push: { branches: [main] }
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm test |
| Deploy via SSH | deploy:
needs: test
runs-on: ubuntu-latest
steps:
- uses: appleboy/ssh-action@v1
with:
host: ${{ secrets.DEPLOY_HOST }}
username: deploy
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: cd /var/www && git pull && npm install --production && pm2 reload all |
| Matrix build (multi Node version) | strategy:
matrix:
node: [18, 20, 22]
steps:
- uses: actions/setup-node@v4
with: { node-version: ${{ matrix.node }} } |
| Docker build + push | - uses: docker/build-push-action@v5
with:
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }} |
| Scheduled workflow (cron) | on:
schedule:
- cron: '0 2 * * *' # daily at 2 AM UTC |
::add-mask:: or sensitive steps with if: env checkif: github.ref == 'refs/heads/main'To set up Continuous Integration and Continuous Deployment (CI/CD) in GitHub Actions, create a workflow file in your repository's .github/workflows directory. Define jobs and steps using the YAML syntax, specifying triggers like push or pull_request. Use actions for tasks like building, testing, and deploying your application. For example, use actions/checkout@v2 to check out your code and actions/setup-node@v2 for Node.js applications.
GitHub Actions provides a powerful automation framework that integrates seamlessly with GitHub repositories. To harness its full potential, you need to understand the fundamental components of a workflow.
A workflow is defined in a YAML file located in the .github/workflows directory of your repository. Each workflow can contain multiple jobs, which run in parallel or sequentially. Each job consists of a series of steps that specify the actions to be taken. The basic structure of a workflow file is as follows:
name: CI/CD Workflow
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
In this example, the workflow is triggered on every push to the main branch. It checks out the code, sets up Node.js version 14, installs dependencies, and runs tests.
Triggers are the events that initiate the workflow. Common triggers include:
push: Triggers when code is pushed to the repository.pull_request: Triggers when a pull request is created or updated.schedule: Triggers workflows at specified intervals, using cron syntax.workflow_dispatch: Allows manual triggering of workflows.For example, to trigger a workflow every day at 2 AM UTC, you can add the following to your workflow:
on:
schedule:
- cron: '0 2 * * *'
Jobs are defined within the jobs key and can run on different operating systems. Each job consists of a series of steps, which can either be actions or shell commands. Here's how you can define multiple jobs:
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Build
run: npm run build
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to Production
run: ./deploy.sh
The needs keyword specifies that the deploy job should only run after the build job completes successfully.
GitHub Actions offers a marketplace where you can find pre-built actions to streamline your workflows. Common actions include:
actions/checkout: Checks out your repository code.actions/setup-node: Sets up a Node.js environment.docker/build-push-action: Builds and pushes Docker images.To use an action, simply reference it in your steps. For instance:
- name: Build Docker Image
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: user/app:latest
Here’s a complete example of a CI/CD workflow for a Node.js application that includes testing and deployment:
name: CI/CD Workflow
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm test
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to Production
run: ./deploy.sh
This workflow checks out the code, installs dependencies, runs tests, and then deploys the application to production if all previous steps are successful. Ensure your deploy.sh script includes all necessary commands for deployment, and consider adding error handling for robustness.
Setting up CI/CD in GitHub Actions enhances your development workflow by automating testing and deployment processes. By leveraging the flexibility of YAML configurations, you can create sophisticated workflows that improve code quality and speed up delivery times.
For solo project — yes. Team 5+ — sometimes need Teams $4/user/mo or self-hosted runners.
For private network access, unlimited minutes, GPU/ARM runners. Downside — maintenance + security (compromised runner = RCE in workflow).
Secrets — encrypted, not visible in logs. Env vars — plain, visible. For tokens/passwords — always secrets.
GitHub Actions: free for GH repos, huge actions marketplace, YAML. Jenkins: self-host, flexible but maintenance. GitLab CI: tight GitLab integration. For GitHub — Actions default.
Free plan — 10 monitors, checks every 5 min, no card required. Upgrade for 1-minute interval and multi-region monitoring.