GitHub Actions Hands-on Practice Projects

1. Hello World Workflow

A minimal workflow to test trigger mechanics, job execution, and basic logging in GitHub Actions.

YAML

name: Hello World

on:
  push:
    branches: [ "main" ]
  workflow_dispatch:

jobs:
  say-hello:
    runs-on: ubuntu-latest
    steps:
      - name: Print Welcome Message
        run: echo "Hello World from GitHub Actions!"
      
      - name: Display Runner Details
        run: |
          echo "Triggered event: ${{ github.event_name }}"
          echo "Running on branch: ${{ github.ref_name }}"
          echo "Executed by: ${{ github.actor }}"

2. Node.js Build Pipeline

Automates dependencies installation, build scripts execution, and unit tests using Node.js with package manager caching.

YAML

name: Node.js CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linter
        run: npm run lint --if-present

      - name: Build application
        run: npm run build --if-present

      - name: Execute unit tests
        run: npm test

3. Python CI Pipeline

Runs static analysis, dependency installation, and pytest execution for Python projects.

YAML

name: Python CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
          cache: 'pip'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
          pip install pytest flake8

      - name: Lint with flake8
        run: |
          # stop the build if there are Python syntax errors or undefined names
          flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
          # exit-zero treats all errors as warnings.
          flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

      - name: Run Pytest
        run: pytest

4. Java Maven Pipeline

Sets up OpenJDK, caches local Maven dependencies, builds the project, and runs integration tests.

YAML

name: Java CI with Maven

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          java-version: '17'
          distribution: 'temurin'
          cache: maven

      - name: Build with Maven
        run: mvn -B package --file pom.xml

      - name: Run Tests
        run: mvn test

5. Playwright Automation Workflow

Installs system dependencies and browser binaries required to execute Playwright end-to-end tests headless in CI.

YAML

name: Playwright Tests

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  playwright-tests:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright Browsers & OS Dependencies
        run: npx playwright install --with-deps

      - name: Run Playwright tests
        run: npx playwright test

      - name: Upload Playwright Report
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30

6. Selenium Pytest Workflow

Executes Selenium browser automation tests using headless Chrome in a Python environment.

YAML

name: Selenium Pytest Pipeline

on:
  push:
    branches: [ "main" ]

jobs:
  selenium-tests:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.10'
          cache: 'pip'

      - name: Install Dependencies
        run: |
          pip install --upgrade pip
          pip install selenium pytest pytest-xdist

      - name: Run Selenium Tests (Headless Chrome)
        run: pytest tests/ui/ --headless

7. Parallel Browser Execution with a Matrix Strategy

Spins up isolated, parallel runners for multiple browser engine combinations simultaneously to accelerate test execution.

YAML

name: Cross-Browser Matrix Execution

on:
  push:
    branches: [ "main" ]

jobs:
  matrix-test:
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        browser: [chromium, firefox, webkit]
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install dependencies
        run: npm ci

      - name: Install Matrix Browser (${{ matrix.browser }})
        run: npx playwright install ${{ matrix.browser }} --with-deps

      - name: Run Tests on ${{ matrix.browser }}
        run: npx playwright test --project=${{ matrix.browser }}

8. Scheduled Nightly Test Execution

Uses cron scheduling syntax to trigger automated regression suites at a designated time without manual intervention.

YAML

name: Nightly Regression Suite

on:
  schedule:
    # Runs at 00:00 UTC every day
    - cron: '0 0 * * *'
  workflow_dispatch: # Allows manual trigger if needed

jobs:
  nightly-tests:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20

      - name: Install Dependencies
        run: npm ci

      - name: Execute Nightly Regression
        run: npm run test:regression

9. Manual Workflow with User Inputs

Presents interactive inputs in the GitHub UI for standard testing parameters like target environment, target browser, and debug flags.

YAML

name: Manual Test Trigger

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Target Deployment Environment'
        required: true
        default: 'staging'
        type: choice
        options:
          - dev
          - qa
          - staging
          - production
      browser:
        description: 'Browser Choice'
        required: true
        default: 'chrome'
        type: choice
        options:
          - chrome
          - firefox
          - safari
      headless:
        description: 'Run in Headless Mode?'
        required: true
        type: boolean
        default: true

jobs:
  run-custom-test:
    runs-on: ubuntu-latest
    steps:
      - name: Print User Parameters
        run: |
          echo "Running tests against: ${{ inputs.environment }}"
          echo "Selected Browser: ${{ inputs.browser }}"
          echo "Headless mode: ${{ inputs.headless }}"

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Run Suite
        run: |
          echo "Executing test CLI commands with flags..."
          # Example CLI invocation:
          # npm test -- --env=${{ inputs.environment }} --browser=${{ inputs.browser }} --headless=${{ inputs.headless }}

10. Upload HTML and Allure Reports

Executes tests, generates report output, and attaches compiled HTML and Allure report assets to the workflow summary using if: always().

YAML

name: Test Suite with Allure Reporting

on:
  push:
    branches: [ "main" ]

jobs:
  test-and-report:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'

      - name: Install Dependencies
        run: |
          pip install pytest allure-pytest

      - name: Run Tests & Generate Allure Results
        run: pytest --alluredir=allure-results
        continue-on-error: true

      - name: Install Allure CLI & Generate HTML Report
        run: |
          sudo wget https://github.com/allure-framework/allure2/releases/download/2.24.0/allure-2.24.0.tgz
          sudo tar -zxvf allure-2.24.0.tgz -C /opt/
          sudo ln -s /opt/allure-2.24.0/bin/allure /usr/bin/allure
          allure generate allure-results --clean -o allure-report

      - name: Upload Allure HTML Report Artifact
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: allure-html-report
          path: allure-report/
          retention-days: 14

11. Reusable Workflow for Common Test Execution

Defines a modular, parameterized reusable workflow (workflow_call) and demonstrates how a caller workflow invokes it across repositories or jobs.

Standard Reusable Workflow (.github/workflows/reusable-test.yml)

YAML

name: Shared Test Runner

on:
  workflow_call:
    inputs:
      test_suite:
        required: true
        type: string
      node_version:
        required: false
        type: string
        default: '20'
    secrets:
      API_TOKEN:
        required: true

jobs:
  execute-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ inputs.node_version }}
      - run: npm ci
      - name: Run Test Suite
        env:
          API_TOKEN: ${{ secrets.API_TOKEN }}
        run: npm run test:${{ inputs.test_suite }}

Caller Workflow (.github/workflows/main-pipeline.yml)

YAML

name: Main Pipeline

on:
  push:
    branches: [ "main" ]

jobs:
  run-smoke-tests:
    uses: ./.github/workflows/reusable-test.yml
    with:
      test_suite: 'smoke'
      node_version: '20'
    secrets:
      API_TOKEN: ${{ secrets.SMOKE_API_TOKEN }}

12. Docker Build and Publish Pipeline

Authenticates to Docker Hub (or GHCR), configures Docker Buildx, and pushes a multi-arch container image.

YAML

name: Docker Build and Publish

on:
  push:
    tags:
      - 'v*.*.*'
    branches:
      - 'main'

jobs:
  docker-build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Extract Metadata (Tags, Labels)
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ secrets.DOCKERHUB_USERNAME }}/my-app

      - name: Build and Push Docker Image
        uses: docker/build-push-action@v6
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

13. Deploy to AWS EC2

Connects to AWS using OpenID Connect (OIDC) and deploys updated application builds to an EC2 target via SSH.

YAML

name: Deploy to AWS EC2

on:
  push:
    branches: [ "main" ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Configure AWS Credentials (OIDC)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsEC2DeployRole
          aws-region: us-east-1

      - name: Deploy to EC2 via SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ec2-user
          key: ${{ secrets.EC2_SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            npm install --production
            pm2 restart all

14. Trigger One Workflow from Another

Uses the workflow_run event trigger to execute a downstream automation workflow automatically after an upstream workflow finishes.

Downstream Workflow (.github/workflows/deploy-on-ci-success.yml)

YAML

name: Deployment Triggered by CI Success

on:
  workflow_run:
    workflows: ["Node.js CI"]  # Name of upstream workflow
    types:
      - completed

jobs:
  on-success:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'success' }}
    steps:
      - name: Run Downstream Task
        run: echo "Upstream CI succeeded! Starting deployment process..."
        
  on-failure:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'failure' }}
    steps:
      - name: Notify Team of Failure
        run: echo "Upstream CI failed. Aborting downstream triggers."

15. Multi-Environment Deployment (Dev → QA → Staging → Production)

Establishes sequential environment promotion chains using needs conditions, protected environments, and manual gating rules.

YAML

name: Multi-Environment Promotion Pipeline

on:
  push:
    branches: [ "main" ]

jobs:
  deploy-dev:
    name: Deploy to Development
    runs-on: ubuntu-latest
    environment: dev
    steps:
      - uses: actions/checkout@v4
      - name: Run Dev Deployment
        run: echo "Deploying build commit ${{ github.sha }} to DEV environment"

  deploy-qa:
    name: Deploy to QA
    needs: deploy-dev
    runs-on: ubuntu-latest
    environment: qa
    steps:
      - uses: actions/checkout@v4
      - name: Run QA Deployment
        run: echo "Deploying build commit ${{ github.sha }} to QA environment"

  deploy-staging:
    name: Deploy to Staging
    needs: deploy-qa
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
      - name: Run Staging Deployment
        run: echo "Deploying build commit ${{ github.sha }} to STAGING environment"

  deploy-production:
    name: Deploy to Production
    needs: deploy-staging
    runs-on: ubuntu-latest
    # Requires manual reviewer approval set up under GitHub Environment rules
    environment: production
    steps:
      - uses: actions/checkout@v4
      - name: Run Production Deployment
        run: echo "Deploying build commit ${{ github.sha }} to PRODUCTION environment"

Leave a Comment