Skip to content

Github_actions

GitHub Actions is GitHub’s native CI/CD platform for automating workflows.

┌─────────────────────────────────────────────────────────────────────────────┐
│ GitHub Actions Overview │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ GitHub Actions Concept │ │
│ │ │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ Trigger │───▶│ Workflow │───▶│ Job/Step │ │ │
│ │ │ (push) │ │ (.yml) │ │ (action) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │
│ │ │ │
│ │ Key Features: │ │
│ │ ✓ Native GitHub integration │ │
│ │ ✓ Free for public repos │ │
│ │ ✓ Large action marketplace │ │
│ │ ✓ Matrix builds │ │
│ │ ✓ Container support │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
.github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
DOCKER_REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- name: Cache Maven packages
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-m2-
- name: Build with Maven
run: mvn clean package
- name: Run tests
run: mvn test
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: jar-files
path: target/*.jar
.github/workflows/build-test.yml
name: Build and Test
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
java: [11, 17, 21]
steps:
- uses: actions/checkout@v4
- name: Set up JDK ${{ matrix.java }}
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
- name: Cache Maven
uses: actions/cache@v3
with:
path: ~/.m2
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
- name: Run tests
run: mvn test -B
- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results-java-${{ matrix.java }}
path: target/surefire-reports/*.xml
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run linter
run: |
npm install
npm run lint
- name: Check security
uses: snyk/actions@v1
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
build-docker:
needs: test
runs-on: ubuntu-latest
if: github.event_name == 'push'
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:${{ github.sha }}
ghcr.io/${{ github.repository }}:latest
.github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-staging:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/develop'
environment: staging
steps:
- uses: actions/checkout@v4
- name: Deploy to Staging
run: |
echo "Deploying to staging..."
# Add deployment commands
kubectl config use-context staging
kubectl apply -f k8s/staging/
outputs:
url: ${{ steps.deploy.outputs.url }}
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
environment: production
steps:
- uses: actions/checkout@v4
- name: Deploy to Production
run: |
echo "Deploying to production..."
# Add deployment commands
kubectl config use-context production
kubectl apply -f k8s/production/
.github/workflows/docker-multi.yml
name: Docker Build
on:
push:
branches: [main]
tags: ['v*']
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
myapp
ghcr.io/${{ github.repository }}
tags: |
type=ref,event=branch
type=sha,prefix=
type=raw,value={{version}},enable={{is_default_branch}}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
.github/workflows/matrix.yml
name: Matrix Build
on: [push]
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
node: 18
python: '3.10'
- os: ubuntu-latest
node: 20
python: '3.11'
- os: windows-latest
node: 18
- os: macos-latest
node: 18
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
build:
needs: test
runs-on: ubuntu-latest
strategy:
matrix:
target:
- staging
- production
- development
steps:
- uses: actions/checkout@v4
- name: Build for ${{ matrix.target }}
run: |
echo "Building for ${{ matrix.target }}"
npm run build:${{ matrix.target }}
# .github/workflows/build.yml (Reusable)
name: Build Workflow
on:
workflow_call:
inputs:
java-version:
type: string
default: '17'
secrets:
token:
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: ${{ inputs.java-version }}
- name: Build
run: mvn clean package
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: target/*.jar
# .github/workflows/ci.yml (Using reusable workflow)
name: CI
on: [push]
jobs:
build:
uses: ./.github/workflows/build.yml
secrets:
token: ${{ secrets.GITHUB_TOKEN }}
┌─────────────────────────────────────────────────────────────────────────────┐
│ GitHub Actions Security Best Practices │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Secrets Management │
│ ✓ Use encrypted secrets │
│ ✓ Never log secrets │
│ ✓ Use environment protection rules │
│ │
│ 2. Permissions │
│ ✓ Use minimal permissions │
│ ✓ Use fine-grained tokens │
│ ✓ Review required scopes │
│ │
│ 3. Code Security │
│ ✓ Enable Dependabot │
│ ✓ Use code scanning │
│ ✓ Review actions before using │
│ │
│ 4. Supply Chain Security │
│ ✓ Pin action versions │
│ ✓ Use trusted actions │
│ ✓ Review third-party actions │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
.github/workflows/secure-ci.yml
name: Secure CI
on:
push:
branches: [main]
permissions:
contents: read
issues: write
pull-requests: write
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Run Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload results to GitHub Security
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: 'trivy-results.sarif'

In this chapter, you learned:

  • GitHub Actions Overview: Native CI/CD platform
  • Workflow Structure: Basic workflow syntax
  • Building and Testing: Maven, npm, Docker builds
  • Deployments: Staging and production
  • Docker Multi-Platform: Multi-arch builds
  • Matrix Builds: Testing across configurations
  • Reusable Workflows: DRY principle
  • Security Best Practices: Secrets, permissions, supply chain