AI Cloud
- Cloud Native Product Development
- Cloud Native FaaS
- Monolith to Microservices
- DevSecOps as a Service
- Kubernetes Zero Downtime
Reducing CI pipeline time in GitHub Actions is essential for maintaining high developer velocity, improving feedback loops, and cutting down cloud resource costs. Hereβs a detailed approach with strategies and best practices:
jobs:
lint:
...
test:
...
build:
...
strategy:
matrix:
node: [16, 18, 20]
- uses: actions/cache@v4
with:
path: ~/.npm
key: $-node-$
paths
, paths-ignore
, or if:
conditionals to skip workflows on unrelated changes.on:
push:
paths:
- 'src/**'
- '.github/workflows/**'
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
Separate CI (build, test) from CD (deploy) workflows.
main
or manual dispatch.continue-on-error: false
(default) to halt jobs when a failure occurs.If build artifacts are required in later jobs (e.g., Docker images or binaries), upload them instead of rebuilding.
- uses: actions/upload-artifact@v4
- uses: actions/download-artifact@v4
pytest-xdist
, jest --runInBand
).In Docker-based workflows, optimize Dockerfile
with:
.dockerignore
to limit context sizeworkflow_dispatch
or repository_dispatch
for manually triggered or conditional long-running jobs.Optimization | Time Saved |
---|---|
Caching npm deps | ~30-90 seconds |
Skipping jobs using paths |
Up to 100% |
Parallel matrix testing | ~50-70% reduction |
Using self-hosted runners | ~10-30 seconds per job |
# File: .github/workflows/ci.yaml
name: CI Pipeline
on:
push:
branches: [main]
paths:
- 'src/**'
- '.github/workflows/**'
pull_request:
paths:
- 'src/**'
- '.github/workflows/**'
workflow_dispatch:
jobs:
lint:
name: Lint Code
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Linter
run: npm run lint
test:
name: Run Unit Tests
runs-on: ubuntu-latest
strategy:
matrix:
node: [18, 20]
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v4
- name: Use Node.js $
uses: actions/setup-node@v4
with:
node-version: $
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Tests
run: npm test
build:
name: Build Application
runs-on: ubuntu-latest
needs: [test]
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- name: Cache Build Artifacts
uses: actions/cache@v4
with:
path: .next/cache
key: $-next-$
- name: Build App
run: npm run build
- name: Upload Build Artifacts
uses: actions/upload-artifact@v4
with:
name: app-build
path: .next/
notify:
name: Slack Notification
runs-on: ubuntu-latest
if: failure()
steps:
- name: Send Slack Alert
run: |
curl -X POST -H 'Content-type: application/json' \
--data '{"text":"π¨ CI failed for $ on $"}' \
$
Use this to measure and track improvements as you optimize.
Job Name | Time Before | Time After | % Improvement | Optimization Applied |
---|---|---|---|---|
checkout |
15s | 15s | 0% | - |
lint |
30s | 20s | 33% | Fast-fail, fewer files |
test |
180s | 80s | 55% | Matrix, cache |
build |
150s | 100s | 33% | Dependency & layer cache |
notify |
10s | 10s | 0% | - |
Total Time | ~385s | ~225s | ~42% | Multiple improvements |
.github/
βββ workflows/
βββ ci.yaml
src/
βββ service-a/
βββ service-b/
βββ ...
package-lock.json
Dockerfile
Great! Hereβs a GitHub Actions deployment workflow (CD) that supports:
This example assumes youβre using Helm for deployment and GitHub Actions for automation. ArgoCD integration is included optionally.
cd.yaml
)# File: .github/workflows/cd.yaml
name: Deploy to Kubernetes
on:
workflow_dispatch:
inputs:
environment:
type: choice
description: 'Select environment'
required: true
options:
- staging
- production
version:
description: 'Docker Image Tag (e.g., v1.2.3)'
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: $
url: https://your-app.example.com
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Set Context & Variables
run: |
echo "ENVIRONMENT=$" >> $GITHUB_ENV
echo "VERSION=$" >> $GITHUB_ENV
- name: Set up kubectl
uses: azure/setup-kubectl@v4
with:
version: 'latest'
- name: Set up Helm
uses: azure/setup-helm@v4
with:
version: 'v3.13.0'
- name: Configure Kubeconfig
run: |
echo "$" | base64 -d > kubeconfig
export KUBECONFIG=$PWD/kubeconfig
- name: Helm Canary Deployment
run: |
helm upgrade --install my-app ./helm-chart \
--namespace $ENVIRONMENT \
--set image.tag=$VERSION \
--set deploymentStrategy=canary
approval:
needs: deploy
if: github.event.inputs.environment == 'production'
runs-on: ubuntu-latest
environment:
name: production
url: https://your-app.example.com
steps:
- name: Manual Approval
uses: hmarr/auto-approve-action@v3
with:
github-token: $
rollback:
needs: deploy
if: failure()
runs-on: ubuntu-latest
steps:
- name: Rollback via Helm
run: |
helm rollback my-app 1 --namespace $ENVIRONMENT
Your values.yaml
must support:
deploymentStrategy: "canary"
canary:
enabled: true
weight: 10
You can control traffic % using Istio, Linkerd, or nginx annotations if needed.
You can rollback using:
helm rollback
(as in the example above)argocd app rollback my-app --revision <old-revision>
Set the following in your GitHub repository secrets:
KUBECONFIG_BASE64
(your base64 encoded kubeconfig)GITHUB_TOKEN
ARGOCD_TOKEN
, ARGOCD_SERVER
for ArgoCD CLI integrationKubeify's team decrease the time it takes to adopt open source technology while enabling consistent application environments across deployments... letting our developers focus on application code while improving speed and quality of our releases.
β Yaron Oren, Founder Maverick.ai (acquired by OutboundWorks)
Let us know what you are working on?
We would help you to build a
fault tolerant, secure and scalable system over kubernetes.