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 1AZURE_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:
Health endpoint response after deployment:
Hello endpoint response:
Next Steps¶
See Also¶
- Tutorial Overview & Plan Chooser
- Java Language Guide
- Platform: Hosting Plans
- Operations: Deployment
- Recipes Index