Skip to content

06 - CI/CD (Consumption)

Automate build, test, and deployment using GitHub Actions so every change ships through the same pipeline.

Prerequisites

Tool Version Purpose
JDK 17+ Compile and run Java functions locally
Maven 3.6+ Build and package Java artifacts
Azure Functions Core Tools v4 Start local host and publish artifacts
Azure CLI 2.61+ Provision Azure resources and inspect app state

Consumption plan basics

Consumption (Y1) is serverless with scale-to-zero, up to 200 instances, 1.5 GB memory per instance, and a default 5-minute timeout (max 10 minutes).

What You'll Build

You will configure a GitHub Actions pipeline that builds and deploys a Java Function App, then verify the release with a smoke test and workflow run evidence.

flowchart LR
    A[Push to main] --> B[GitHub Actions]
    B --> C[Maven build and test]
    C --> D[Publish from staging dir]
    D --> E[Smoke test]

Steps

Step 1 - Get the publish profile

Download the publish profile for use in GitHub Actions:

az functionapp deployment list-publishing-profiles \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --xml

Step 2 - Store deployment secrets in GitHub

Add repository secrets:

  • AZURE_FUNCTIONAPP_PUBLISH_PROFILE — paste the XML from Step 1
  • AZURE_FUNCTIONAPP_NAME — your function app name (e.g., func-jcon-04100022)

Step 3 - Create workflow file

name: deploy-java-function

on:
  push:
    branches: [ main ]
    paths:
      - 'apps/java/**'

env:
  JAVA_VERSION: '17'
  AZURE_FUNCTIONAPP_NAME: ${{ secrets.AZURE_FUNCTIONAPP_NAME }}
  POM_XML_DIRECTORY: 'apps/java'
  POM_FUNCTIONAPP_NAME: 'azure-functions-java-guide'

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Set up JDK
        uses: actions/setup-java@v4
        with:
          distribution: temurin
          java-version: ${{ env.JAVA_VERSION }}

      - name: Build with Maven
        run: mvn --batch-mode clean package
        working-directory: ${{ env.POM_XML_DIRECTORY }}

      - name: Deploy to Azure Functions
        uses: Azure/functions-action@v1
        with:
          app-name: ${{ env.AZURE_FUNCTIONAPP_NAME }}
          package: '${{ env.POM_XML_DIRECTORY }}/target/azure-functions/${{ env.POM_FUNCTIONAPP_NAME }}'
          publish-profile: ${{ secrets.AZURE_FUNCTIONAPP_PUBLISH_PROFILE }}

Deploy from staging directory, not project root

The package path must point to the Maven staging directory (target/azure-functions/<appName>/) where function.json files are generated. Deploying from the project root will result in 0 functions being indexed.

Step 4 - Add post-deployment smoke test

Add a smoke test step after deployment:

      - name: Smoke test
        run: |
          sleep 30
          HTTP_STATUS=$(curl --silent --output /dev/null --write-out "%{http_code}" \
            "https://${{ env.AZURE_FUNCTIONAPP_NAME }}.azurewebsites.net/api/health")
          if [ "$HTTP_STATUS" -ne 200 ]; then
            echo "Smoke test failed with status $HTTP_STATUS"
            exit 1
          fi
          echo "Smoke test passed with status $HTTP_STATUS"

Step 5 - Validate the release

# Check function app last modified time
az functionapp show \
  --name "$APP_NAME" \
  --resource-group "$RG" \
  --query "lastModifiedTimeUtc" \
  --output tsv

# Test health endpoint
curl --request GET "https://$APP_NAME.azurewebsites.net/api/health"

# Test hello endpoint
curl --request GET "https://$APP_NAME.azurewebsites.net/api/hello/CICD"

Use GitHub Actions run history as the deployment timeline of record (Actions tab → workflow runs → latest commit SHA), and compare it with lastModifiedTimeUtc to confirm release timing.

Verification

Maven build output:

[INFO] BUILD SUCCESS
[INFO] Total time:  8.234 s

Health endpoint response after deployment:

{"status":"healthy","timestamp":"2026-04-09T16:34:06.830Z","version":"1.0.0"}

Hello endpoint response:

{"message":"Hello, CICD"}

Next Steps

Next: 07 - Extending with Triggers

See Also

Sources