Problem Statement
Explain GitHub Actions workflow syntax comprehensively. Include events, jobs, steps, actions, contexts, and advanced patterns.
Explanation
GitHub Actions workflow starts with name and trigger events:
```yaml
name: CI/CD Pipeline
on:
push:
branches: [ main, develop ]
paths:
- 'src/**'
pull_request:
branches: [ main ]
schedule:
- cron: '0 2 * * *' # Daily at 2 AM
workflow_dispatch: # Manual trigger
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'staging'
```
Jobs define workflow tasks running in parallel by default. Jobs can have dependencies using needs:
```yaml
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: npm install
- run: npm run build
- uses: actions/upload-artifact@v3
with:
name: dist
path: dist/
test:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
name: dist
- run: npm test
deploy:
needs: [build, test]
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- run: ./deploy.sh
```
Steps are individual tasks in job. Steps can run commands (run) or use actions (uses):
```yaml
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
env:
NODE_ENV: test
```
Actions are reusable units from marketplace or custom. Actions have inputs (with) and outputs:
```yaml
- uses: docker/build-push-action@v4
with:
context: .
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/myapp:latest
cache-from: type=gha
cache-to: type=gha,mode=max
```
Contexts provide information about workflow run:
```yaml
steps:
- name: Print context info
run: |
echo "Event: ${{ github.event_name }}"
echo "Branch: ${{ github.ref }}"
echo "Commit: ${{ github.sha }}"
echo "Actor: ${{ github.actor }}"
echo "Runner OS: ${{ runner.os }}"
echo "Job status: ${{ job.status }}"
```
Secrets access sensitive data:
```yaml
- name: Deploy
run: ./deploy.sh
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
```
Matrix strategy for multiple configurations:
```yaml
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node: [14, 16, 18]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
```
Conditionals control step/job execution:
```yaml
steps:
- name: Deploy to staging
if: github.ref == 'refs/heads/develop'
run: ./deploy-staging.sh
- name: Deploy to production
if: github.ref == 'refs/heads/main' && success()
run: ./deploy-prod.sh
```
Environments for deployment protection:
```yaml
jobs:
deploy:
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
steps:
- run: ./deploy.sh
```
Environments can have required reviewers and wait timers.
Reusable workflows enable workflow composition:
```yaml
# .github/workflows/reusable-deploy.yml
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
deploy-key:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: ./deploy.sh ${{ inputs.environment }}
env:
DEPLOY_KEY: ${{ secrets.deploy-key }}
# .github/workflows/main.yml
jobs:
deploy-staging:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: staging
secrets:
deploy-key: ${{ secrets.STAGING_KEY }}
```
Understanding GitHub Actions syntax enables building sophisticated workflows with proper dependency management, reusability, and integration with GitHub ecosystem.