This document delivers detailed, professional CI/CD pipeline configurations for GitHub Actions, GitLab CI, and Jenkins. These configurations are designed to automate the linting, testing, building, and deployment stages for a typical web application, providing a robust foundation for your development workflow.
This deliverable provides ready-to-use, yet highly customizable, CI/CD pipeline definitions tailored for three leading platforms: GitHub Actions, GitLab CI, and Jenkins. The primary goal is to empower your team with automated processes that ensure code quality, rapid feedback, and efficient deployments, accelerating your software delivery lifecycle.
Each configuration includes:
These templates are designed to be a starting point, illustrating best practices and providing a solid foundation that you can adapt to your specific project needs.
To provide concrete and actionable examples, the following assumptions have been made regarding the application and target environment. Please review these as you consider adapting the configurations.
npm for package management and scripting). This is chosen for its versatility, allowing for both frontend (e.g., React, Vue, Angular) and backend (e.g., Express, NestJS) application contexts.eslint).jest). * npm install: Dependency installation.
* npm run build: Script for compiling/bundling frontend assets (e.g., Webpack, Rollup).
* docker build: For containerizing backend services.
* Frontend: Static assets deployed to AWS S3 (Amazon Simple Storage Service) with CloudFront distribution (though CloudFront setup is beyond the scope of this pipeline, S3 sync is covered).
* Backend: Docker image built and pushed to Amazon ECR (Elastic Container Registry). Further deployment to AWS ECS/EKS/EC2 is a subsequent step after the image is in ECR.
package.json, Dockerfile, .eslintrc.js, jest.config.js, etc. For simplicity, a monolithic structure is assumed, but these principles extend to monorepos.Disclaimer: These configurations are templates. They require customization to match your exact repository structure, build commands, test scripts, environment variables, and deployment targets.
All provided pipeline configurations adhere to a common set of stages to ensure comprehensive automation:
* Purpose: Enforce code style, identify potential errors, and maintain code quality standards.
* Action: Runs static code analysis tools (e.g., ESLint).
* Outcome: Fails the pipeline if linting rules are violated.
* Purpose: Verify the correctness and functionality of the application code.
* Action: Executes unit, integration, and potentially end-to-end tests.
* Outcome: Fails the pipeline if any tests fail.
* Purpose: Compile source code, resolve dependencies, and package the application into deployable artifacts.
* Action:
* For frontend: Installs dependencies, runs npm run build to generate static assets.
* For backend: Builds a Docker image based on a Dockerfile.
* Outcome: Produces build artifacts (e.g., compiled JS files, Docker image) ready for deployment.
* Purpose: Release the built artifacts to specified environments (e.g., Development, Staging, Production).
* Action:
* For frontend: Synchronizes static assets to an AWS S3 bucket.
* For backend: Pushes the Docker image to Amazon ECR.
* Outcome: Application updates are live in the target environment or available for further orchestration.
.github/workflows/main.yml)GitHub Actions provides a flexible, event-driven CI/CD platform deeply integrated with GitHub repositories.
# .github/workflows/main.yml
name: Node.js CI/CD Pipeline
on:
push:
branches:
- main
pull_request:
branches:
- main
env:
NODE_VERSION: '18' # Specify Node.js version
AWS_REGION: 'us-east-1' # Your AWS region
jobs:
lint:
name: Lint Code
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm' # Cache npm dependencies for faster builds
- name: Install dependencies
run: npm ci # Use npm ci for clean installs in CI environments
- name: Run ESLint
run: npm run lint # Assumes 'lint' script in package.json
test:
name: Run Tests
runs-on: ubuntu-latest
needs: lint # This job depends on 'lint' completing successfully
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run Jest tests
run: npm test # Assumes 'test' script in package.json
build-and-push-backend:
name: Build & Push Backend Docker Image
runs-on: ubuntu-latest
needs: test # This job depends on 'test' completing successfully
if: github.ref == 'refs/heads/main' # Only run on pushes to main branch
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push Docker image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
ECR_REPOSITORY: ${{ secrets.ECR_REPOSITORY }} # e.g., my-backend-app
IMAGE_TAG: ${{ github.sha }} # Use commit SHA as image tag
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "Docker image pushed: $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
build-and-deploy-frontend:
name: Build & Deploy Frontend to S3
runs-on: ubuntu-latest
needs: test # This job depends on 'test' completing successfully
if: github.ref == 'refs/heads/main' # Only run on pushes to main branch
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build frontend
run: npm run build # Assumes 'build' script in package.json, outputting to a 'dist' folder
env:
CI: true # Prevents warnings from turning into errors in some React setups
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Deploy to S3
run: |
aws s3 sync ./dist/ s3://${{ secrets.S3_BUCKET_NAME }} --delete # Sync 'dist' folder to S3
env:
S3_BUCKET_NAME: ${{ secrets.S3_BUCKET_NAME }} # e.g., my-frontend-bucket
This document details the comprehensive analysis of infrastructure needs required for generating robust and efficient CI/CD pipeline configurations. This foundational step ensures that the proposed pipeline design is perfectly aligned with your existing environment, technical requirements, scalability demands, and security policies.
The primary objective of the "Analyze Infrastructure Needs" step is to gather and evaluate critical information about your current and desired operational landscape. This includes understanding your source code management (SCM) platform, target deployment environments, existing toolchains, security mandates, and performance expectations. The insights derived here will directly inform the selection of the most suitable CI/CD platform (GitHub Actions, GitLab CI, Jenkins) and dictate the specific configurations for testing, linting, building, and deployment stages.
By meticulously analyzing these needs, we aim to:
A thorough infrastructure analysis covers several critical dimensions, each impacting the design and functionality of your CI/CD pipelines.
* GitHub: GitHub.com, GitHub Enterprise (Self-hosted/Cloud)
* GitLab: GitLab.com, GitLab CE/EE (Self-hosted)
* Bitbucket: Bitbucket Cloud, Bitbucket Server/Data Center
* Azure Repos: Part of Azure DevOps
* Other: (e.g., AWS CodeCommit, SVN, Perforce)
* GitHub Actions: Cloud-native, tightly integrated with GitHub.
* GitLab CI: Integrated within GitLab, strong for end-to-end DevSecOps.
* Jenkins: Highly flexible, self-hosted, extensive plugin ecosystem.
* Other: Azure DevOps Pipelines, CircleCI, Travis CI, Spinnaker, Argo CD.
* Managed Runners: Cloud-hosted, serverless (e.g., GitHub-hosted runners, GitLab.com shared runners).
* Self-Hosted Runners/Agents: On-premises VMs, Docker containers, Kubernetes pods (e.g., Jenkins agents, self-hosted GitHub Actions runners, GitLab runners).
* Java (JDK versions), Maven, Gradle
* Python (versions), pip, Poetry, Conda
* .NET (Core/Framework versions), NuGet
* Node.js (versions), npm, Yarn, pnpm
* Go (versions)
* Ruby (versions), Bundler
* PHP (versions), Composer
* Docker, Kubernetes (kubectl, Helm, kustomize)
* Terraform, Ansible, Pulumi
* Unit Testing: JUnit, Pytest, Jest, NUnit, GoConvey.
* Integration Testing: Testcontainers, Mockito, Cypress, Playwright.
* End-to-End (E2E) Testing: Selenium, Cypress, Playwright, Robot Framework.
* Cloud-Native: Amazon ECR, Azure Container Registry (ACR), Google Container Registry (GCR)/Artifact Registry.
* Platform-Integrated: GitHub Container Registry (GHCR), GitLab Container Registry.
* Universal: Docker Hub, Quay.io.
* Self-hosted: Harbor.
* Universal: JFrog Artifactory, Nexus Repository Manager.
* Cloud-Native: AWS CodeArtifact, Azure Artifacts.
* Virtual Machines (VMs): AWS EC2, Azure VMs, GCP Compute Engine, On-premises VMware/Hyper-V.
* Container Orchestration: Kubernetes (EKS, AKS, GKE, OpenShift, Self-managed), AWS ECS/Fargate, Azure Container Instances (ACI).
* Serverless: AWS Lambda, Azure Functions, Google Cloud Functions.
* Platform as a Service (PaaS): AWS Elastic Beanstalk, Azure App Service, Heroku, Google App Engine.
* Edge Devices/IoT: Specific deployment mechanisms for embedded systems.
* Blue/Green, Canary, Rolling Updates, A/B Testing, Recreate.
* Cloud-Native: AWS Secrets Manager, Azure Key Vault, Google Secret Manager.
* Dedicated Tools: HashiCorp Vault.
* Platform-Integrated: GitHub Secrets, GitLab CI/CD Variables (masked/protected).
The CI/CD landscape is dynamic, with several key trends shaping infrastructure decisions:
Based on the general trends and best practices, here are initial recommendations that will be refined upon gathering your specific infrastructure details:
This analysis provides the critical foundation for designing your CI/CD pipelines. The subsequent steps will leverage these insights to generate concrete configurations.
Your detailed input on the above considerations will enable us to deliver a highly tailored and effective CI/CD solution.
name: The name of your workflow, displayed in GitHub's Actions tab.on: Defines the events that trigger the workflow (e.g., push to main, pull_request to main).env: Global environment variables available to all jobs.This document provides comprehensive, detailed, and actionable CI/CD pipeline configurations for GitHub Actions, GitLab CI, and Jenkins. These pipelines are designed to automate the entire software delivery lifecycle, including linting, testing, building, and deployment, ensuring a robust and efficient development workflow.
This deliverable provides ready-to-use CI/CD pipeline configurations tailored for popular platforms: GitHub Actions, GitLab CI, and Jenkins. The goal is to accelerate your development process by automating repetitive tasks, improving code quality, and ensuring consistent, reliable deployments. Each configuration is detailed, explaining its components and how to adapt it to your specific needs.
The provided pipeline configurations incorporate the following essential stages, designed to cover a typical software development workflow:
To provide concrete examples, we will use a common scenario: a Node.js web application that is containerized with Docker. This scenario allows us to demonstrate linting, testing (Node.js specific), building (Node.js artifact and Docker image), and a generic deployment step using the built Docker image.
my-app/
├── .github/ (for GitHub Actions)
├── .gitlab-ci.yml (for GitLab CI)
├── Jenkinsfile (for Jenkins)
├── src/
│ └── ... (Node.js source files)
├── tests/
│ └── ... (Test files)
├── Dockerfile
├── package.json
├── .eslintrc.js
└── ...
GitHub Actions provides powerful and flexible CI/CD capabilities directly within your GitHub repository. Workflows are defined in YAML files (.yml) stored in the .github/workflows/ directory.
main.yml for GitHub ActionsThis workflow triggers on pushes to the main branch and pull requests, and includes linting, testing, Docker build/push, and a placeholder deployment step.
# .github/workflows/main.yml
name: Node.js CI/CD with Docker
on:
push:
branches:
- main
pull_request:
branches:
- main
env:
NODE_VERSION: '18.x'
DOCKER_IMAGE_NAME: my-node-app
DOCKER_REGISTRY: ghcr.io/${{ github.repository_owner }} # Or your preferred registry like docker.io
jobs:
build-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # Required for ghcr.io
id-token: write # Required for OIDC based deployments
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'npm' # Caches npm dependencies
- name: Install dependencies
run: npm ci
- name: Lint code
run: npm run lint # Assumes 'lint' script in package.json (e.g., 'eslint .')
- name: Run tests
run: npm test # Assumes 'test' script in package.json (e.g., 'jest')
- name: Build Node.js application
run: npm run build # Assumes 'build' script in package.json (e.g., 'webpack' or 'tsc')
- name: Log in to Docker Registry
uses: docker/login-action@v3
with:
registry: ${{ env.DOCKER_REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} # Use GITHUB_TOKEN for ghcr.io, or DOCKER_HUB_TOKEN for Docker Hub
- name: Build and push Docker image
id: docker_build
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:latest
${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:${{ github.sha }} # Tag with commit SHA
cache-from: type=gha # Cache Docker layers using GitHub Actions cache
cache-to: type=gha,mode=max
- name: Deploy to Staging (Example)
# This is a placeholder for your actual deployment logic.
# Replace this with steps specific to your deployment target (e.g., Kubernetes, AWS ECS, Azure App Service).
# This example uses OIDC to authenticate to AWS and trigger an ECS deployment.
if: github.ref == 'refs/heads/main'
run: |
echo "Deploying ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_IMAGE_NAME }}:${{ github.sha }} to Staging..."
# Example for AWS ECS deployment using OIDC:
# - uses: aws-actions/configure-aws-credentials@v4
# with:
# role-to-assume: arn:aws:iam::123456789012:role/github-actions-deploy-role
# aws-region: us-east-1
# - run: |
# aws ecs update-service --cluster my-cluster --service my-service --force-new-deployment \
# --task-definition $(aws ecs register-task-definition --cli-input-json file://task-definition.json | jq -r '.taskDefinition.taskDefinitionArn')
# # You would typically generate task-definition.json dynamically or use tools like Terraform/CloudFormation.
# echo "Deployment complete."
env:
AWS_REGION: us-east-1 # Example AWS region
Explanation:
on: Defines when the workflow runs (push to main, pull requests to main).env: Global environment variables for the workflow.jobs.build-and-deploy: A single job running on ubuntu-latest.permissions: Explicitly grants permissions needed for contents (checkout), packages (push to GHCR), and id-token (for OIDC authentication).actions/checkout@v4: Checks out your repository code.actions/setup-node@v4: Sets up the Node.js environment.npm ci: Installs dependencies securely.npm run lint, npm test, npm run build: Executes your defined scripts for linting, testing, and building.docker/login-action@v3: Authenticates to the specified Docker registry. For GitHub Container Registry (ghcr.io), GITHUB_TOKEN is used. For Docker Hub, you'd use DOCKER_HUB_TOKEN secret.docker/build-push-action@v5: Builds the Docker image from Dockerfile and pushes it to the registry with latest and commit SHA tags.Deploy to Staging (Example): A placeholder for your actual deployment logic. It shows how you might integrate with a cloud provider (e.g., AWS ECS) using OIDC for authentication. You MUST replace this with your specific deployment commands.GITHUB_TOKEN is automatically provided by GitHub. For other registries or cloud provider credentials, use GitHub Secrets (e.g., DOCKER_HUB_USERNAME, DOCKER_HUB_TOKEN, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY).GitLab CI/CD is integrated directly into GitLab. Pipelines are defined in a .gitlab-ci.yml file at the root of your repository.
.gitlab-ci.yml for GitLab CIThis pipeline defines stages for linting, testing, building, Docker build/push, and deployment, triggered on pushes to the main branch.
# .gitlab-ci.yml
stages:
- lint
- test
- build
- containerize
- deploy
variables:
NODE_VERSION: '18.x'
DOCKER_IMAGE_NAME: $CI_REGISTRY_IMAGE # Uses GitLab's built-in registry variable
DOCKER_TAG: $CI_COMMIT_SHA # Tags with commit SHA
DOCKER_LATEST_TAG: latest
cache:
paths:
- node_modules/
lint:
stage: lint
image: node:$NODE_VERSION-alpine
script:
- npm ci
- npm run lint # Assumes 'lint' script in package.json (e.g., 'eslint .')
artifacts:
expire_in: 1 week
test:
stage: test
image: node:$NODE_VERSION-alpine
script:
- npm ci
- npm test # Assumes 'test' script in package.json (e.g., 'jest')
artifacts:
when: always
reports:
junit:
- junit.xml # If your test runner generates JUnit reports
expire_in: 1 week
build_app:
stage: build
image: node:$NODE_VERSION-alpine
script:
- npm ci
- npm run build # Assumes 'build' script in package.json (e.g., 'webpack' or 'tsc')
artifacts:
paths:
- dist/ # Or your build output directory
expire_in: 1 week
containerize_app:
stage: containerize
image: docker:latest
services:
- docker:dind # Docker in Docker for building images
script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY # Login to GitLab's built-in registry
- docker build -t $DOCKER_IMAGE_NAME:$DOCKER_TAG -t $DOCKER_IMAGE_NAME:$DOCKER_LATEST_TAG .
- docker push $DOCKER_IMAGE_NAME:$DOCKER_TAG
- docker push $DOCKER_IMAGE_NAME:$DOCKER_LATEST_TAG
only:
- main # Only build and push Docker image for main branch
deploy_staging:
stage: deploy
image: alpine/helm:3.8.2 # Example image for Kubernetes deployment
# Replace with your deployment tool's image (e.g., AWS CLI, Azure CLI, gcloud)
script:
- echo "Deploying $DOCKER_IMAGE_NAME:$DOCKER_TAG to Staging..."
# Example for Kubernetes deployment using Helm:
# - helm upgrade --install my-app ./helm-chart --set image.tag=$DOCKER_TAG --namespace
\n