Skip to content

st0rm-bless3d/github-actions-azure

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 

Repository files navigation

github-actions-azure

Production-ready CI/CD workflows for deploying applications to Azure. Includes workflows for Static Web Apps, Azure Functions, and container deployments.

Workflows

Workflow Purpose
azure-static-web-app.yml Deploy React/Vue/Angular apps to Azure Static Web Apps
azure-functions-node.yml Deploy Node.js/TypeScript Azure Functions
azure-functions-python.yml Deploy Python Azure Functions
pr-validation.yml Run linting, type checking, and tests on pull requests
infrastructure-deploy.yml Deploy Bicep/ARM infrastructure templates

Usage

Copy the workflow file you need to your repository's .github/workflows/ directory and configure the required secrets.


Azure Static Web Apps

Deploys a frontend application (React, Vue, Angular, etc.) to Azure Static Web Apps with automatic preview environments for pull requests.

File: azure-static-web-app.yml

name: Deploy Static Web App

on:
  push:
    branches: [main]
  pull_request:
    types: [opened, synchronize, reopened, closed]
    branches: [main]

env:
  APP_LOCATION: "src"
  API_LOCATION: "api"
  OUTPUT_LOCATION: "dist"

jobs:
  build_and_deploy:
    if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed')
    runs-on: ubuntu-latest
    name: Build and Deploy
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          submodules: true

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'
          cache-dependency-path: '${{ env.APP_LOCATION }}/package-lock.json'

      - name: Install dependencies
        run: npm ci
        working-directory: ${{ env.APP_LOCATION }}

      - name: Build
        run: npm run build
        working-directory: ${{ env.APP_LOCATION }}
        env:
          VITE_API_URL: ${{ vars.API_URL }}

      - name: Deploy to Azure Static Web Apps
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
          repo_token: ${{ secrets.GITHUB_TOKEN }}
          action: "upload"
          app_location: ${{ env.APP_LOCATION }}
          api_location: ${{ env.API_LOCATION }}
          output_location: ${{ env.OUTPUT_LOCATION }}

  close_pull_request:
    if: github.event_name == 'pull_request' && github.event.action == 'closed'
    runs-on: ubuntu-latest
    name: Close PR Preview
    
    steps:
      - name: Close Pull Request
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }}
          action: "close"

Required Secrets:

  • AZURE_STATIC_WEB_APPS_API_TOKEN - Deployment token from Azure portal

Optional Variables:

  • API_URL - API endpoint for the frontend to call

Azure Functions (Node.js)

Deploys a Node.js or TypeScript Azure Functions app with staging slot deployment and swap.

File: azure-functions-node.yml

name: Deploy Azure Functions

on:
  push:
    branches: [main, develop]
  workflow_dispatch:

env:
  AZURE_FUNCTIONAPP_NAME: 'your-function-app'
  AZURE_FUNCTIONAPP_PACKAGE_PATH: 'functions'
  NODE_VERSION: '20.x'

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

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: 'npm'
          cache-dependency-path: '${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/package-lock.json'

      - name: Install dependencies
        run: npm ci
        working-directory: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}

      - name: Build
        run: npm run build
        working-directory: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}

      - name: Run tests
        run: npm test
        working-directory: ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}

      - name: Upload artifact
        uses: actions/upload-artifact@v4
        with:
          name: functions
          path: |
            ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/dist
            ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/host.json
            ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/package.json
            ${{ env.AZURE_FUNCTIONAPP_PACKAGE_PATH }}/package-lock.json

  deploy-staging:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    environment: staging
    
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: functions
          path: ./deploy

      - name: Install production dependencies
        run: npm ci --production
        working-directory: ./deploy

      - name: Login to Azure
        uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy to staging slot
        uses: Azure/functions-action@v1
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
          package: './deploy'
          slot-name: 'staging'

  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment: production
    
    steps:
      - name: Login to Azure
        uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Swap staging to production
        run: |
          az functionapp deployment slot swap \
            --resource-group ${{ vars.RESOURCE_GROUP }} \
            --name ${{ env.AZURE_FUNCTIONAPP_NAME }} \
            --slot staging \
            --target-slot production

  deploy-develop:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/develop'
    environment: development
    
    steps:
      - name: Download artifact
        uses: actions/download-artifact@v4
        with:
          name: functions
          path: ./deploy

      - name: Install production dependencies
        run: npm ci --production
        working-directory: ./deploy

      - name: Login to Azure
        uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy to dev
        uses: Azure/functions-action@v1
        with:
          app-name: '${{ env.AZURE_FUNCTIONAPP_NAME }}-dev'
          package: './deploy'

Required Secrets:

  • AZURE_CREDENTIALS - Service principal credentials (JSON format)

Required Variables:

  • RESOURCE_GROUP - Azure resource group name

PR Validation

Runs linting, type checking, and tests on every pull request. Blocks merge if checks fail.

File: pr-validation.yml

name: PR Validation

on:
  pull_request:
    branches: [main, develop]

jobs:
  validate:
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout
        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: Lint
        run: npm run lint

      - name: Type check
        run: npm run type-check

      - name: Test
        run: npm test -- --coverage

      - name: Build
        run: npm run build

      - name: Upload coverage
        uses: codecov/codecov-action@v4
        with:
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: false

Infrastructure Deployment

Deploys Bicep or ARM templates to Azure.

File: infrastructure-deploy.yml

name: Deploy Infrastructure

on:
  push:
    branches: [main]
    paths:
      - 'infrastructure/**'
  workflow_dispatch:
    inputs:
      environment:
        description: 'Environment to deploy'
        required: true
        default: 'dev'
        type: choice
        options:
          - dev
          - staging
          - prod

env:
  TEMPLATE_FILE: 'infrastructure/main.bicep'

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

      - name: Login to Azure
        uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Validate template
        run: |
          az deployment group validate \
            --resource-group ${{ vars.RESOURCE_GROUP }} \
            --template-file ${{ env.TEMPLATE_FILE }} \
            --parameters infrastructure/parameters.${{ inputs.environment || 'dev' }}.json

  deploy:
    needs: validate
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment || 'dev' }}
    
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Login to Azure
        uses: azure/login@v2
        with:
          creds: ${{ secrets.AZURE_CREDENTIALS }}

      - name: Deploy infrastructure
        run: |
          az deployment group create \
            --resource-group ${{ vars.RESOURCE_GROUP }} \
            --template-file ${{ env.TEMPLATE_FILE }} \
            --parameters infrastructure/parameters.${{ inputs.environment || 'dev' }}.json

Setting Up Azure Credentials

Create a service principal for GitHub Actions:

az ad sp create-for-rbac \
  --name "github-actions-sp" \
  --role contributor \
  --scopes /subscriptions/<subscription-id>/resourceGroups/<resource-group> \
  --sdk-auth

Copy the JSON output and add it as a repository secret named AZURE_CREDENTIALS.

For Static Web Apps, get the deployment token from: Azure Portal > Static Web App > Manage deployment token


Branch Strategy

These workflows assume the following branch strategy:

main (production)
  └── staging slot deployment, then swap to production

develop (development)
  └── direct deployment to dev environment

feature/* (feature branches)
  └── PR validation only, preview environments for Static Web Apps

Modify the branch triggers in each workflow to match your strategy.


Related

About

Production-ready CI/CD workflows for deploying applications to Azure. Includes workflows for Static Web Apps, Azure Functions, and container deployments.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors