Answer
Composite Actions in GitHub Actions
A composite action groups multiple steps into a single reusable block — like a helper function for workflows.
Project Structure
CODE
my-actions/
└── setup-and-test/
└── action.yml ← the composite action
Creating a Composite Action
YAML
# .github/actions/setup-and-test/action.yml
name: 'Setup Java and Run Tests'
description: 'Sets up JDK, caches Maven, and runs TestNG suite'
inputs:
java-version:
description: 'Java version to use'
required: false
default: '17'
browser:
description: 'Browser for tests'
required: false
default: 'chrome'
suite:
description: 'TestNG suite file'
required: false
default: 'testng.xml'
environment:
description: 'Target environment'
required: true
outputs:
test-status:
description: 'Pass or Fail'
value: ${{ steps.run-tests.outcome }}
runs:
using: 'composite' # ← makes this a composite action
steps:
- name: Set up JDK
uses: actions/setup-java@v4
with:
java-version: ${{ inputs.java-version }}
distribution: temurin
cache: maven
- name: Install Chrome
shell: bash
run: |
sudo apt-get update -q
sudo apt-get install -y google-chrome-stable
- name: Run tests
id: run-tests
shell: bash
run: |
mvn test \
-Dbrowser=${{ inputs.browser }} \
-Denv=${{ inputs.environment }} \
-Dsurefire.suiteXmlFiles=${{ inputs.suite }}
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: results-${{ inputs.environment }}-${{ inputs.browser }}
path: target/surefire-reports/
Using the Composite Action
YAML
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
smoke-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup and run smoke tests
uses: ./.github/actions/setup-and-test # local path
# OR from another repo:
# uses: my-org/shared-actions/setup-and-test@v1
with:
browser: chrome
suite: smoke-testng.xml
environment: staging
regression-firefox:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup and run regression on Firefox
uses: ./.github/actions/setup-and-test
with:
browser: firefox
suite: regression-testng.xml
environment: qa
Publish Action to Marketplace (action.yml in root)
YAML
# action.yml (at repo ROOT for marketplace publishing)
name: 'Run Selenium Tests'
description: 'Run Selenium/TestNG automation tests with configurable browser and environment'
author: 'AutomateQA'
branding:
icon: 'play-circle'
color: 'green'
inputs:
browser:
description: 'Browser (chrome/firefox/edge)'
required: false
default: 'chrome'
runs:
using: 'composite'
steps:
- shell: bash
run: echo "Running tests on ${{ inputs.browser }}"
Composite vs JavaScript/Docker Actions
| Composite | JavaScript | Docker | |
|---|---|---|---|
| Language | YAML steps | Node.js | Any language |
| Speed | Medium | Fast | Slowest (pulls image) |
| Complexity | Simple | Medium | Complex |
| Reuse existing Actions | Yes | No | No |
| Best for | Grouping workflow steps | Speed-critical logic | Custom environments |
