A collection of reusable GitHub Actions workflows for streamlined CI/CD processes.
This repository contains reusable GitHub Actions workflows designed to standardize and simplify CI/CD processes across multiple projects. The workflows support:
- π³ Docker image building and pushing to Azure Container Registry and GHCR
- π§ͺ .NET application testing and code coverage
- π Integration with Codecov for coverage reporting
- π¬ Slack notifications for build status
- π Azure authentication using OIDC/Federated Identity
File: .github/workflows/build-push.yaml
A comprehensive reusable workflow that builds .NET applications, runs tests, generates coverage reports, builds Docker images, and pushes them to Azure Container Registry.
- β Input validation and error handling
- π Azure Container Registry authentication via OIDC
- π§ͺ .NET testing with coverage generation
- π³ Docker image building with metadata
- π Codecov integration
- π¬ Slack notifications
- π·οΈ Flexible tagging strategies
- β‘ GitHub Actions caching
| Input | Description | Required | Default |
|---|---|---|---|
app_name |
Application name | β | - |
system_name |
System name | β | - |
environment |
Deployment environment (dev, test, prod) | β | - |
tags |
Docker image tags (comma-separated) | β | - |
solution_name |
.NET solution file name | β | Conferenti.sln |
docker-build-context |
Docker build context path | β | ./ |
container_registry |
Container registry URL | β | conferentiregistry.azurerc.io |
dockerfile |
Path to Dockerfile | β | Dockerfile |
push-image |
Whether to push the image | β | true |
build-args |
Docker build arguments | β | - |
version |
Semantic version for tagging | β | - |
coverage_file_path |
Path to coverage file | β | ./target/site/coverage.cobertura.xml |
dotnet_version |
.NET version to use | β | 9.x |
| Secret | Description | Required |
|---|---|---|
GH_TOKEN |
GitHub Personal Access Token | β |
AZURE_CLIENT_ID |
Azure AD Application Client ID | β |
AZURE_TENANT_ID |
Azure Tenant ID | β |
CODECOV_TOKEN |
Codecov access token | β |
SLACK_WEBHOOK_URL |
Slack webhook URL for notifications | β |
File: .github/workflows/slack-message.yaml
A reusable workflow for sending messages to Slack channels using webhooks.
- β Input validation and error handling
- π¨ Customizable message formatting
- π Color-coded messages (good, warning, danger, or custom hex)
- π± Channel targeting
- π€ Custom username and icon support
| Input | Description | Required | Default |
|---|---|---|---|
channel |
Slack channel to send message to | β | - |
message |
Message to send | β | - |
username |
Username to display | β | GitHub Actions |
icon_emoji |
Emoji icon to use | β | :github: |
color |
Message color (good, warning, danger, or hex) | β | good |
| Secret | Description | Required |
|---|---|---|
SLACK_WEBHOOK_URL |
Slack webhook URL | β |
-
Create Azure AD Application:
az ad app create --display-name "GitHub-Actions-OIDC" -
Configure Federated Identity:
az ad app federated-credential create \ --id <app-id> \ --parameters @federated-credential.json
-
Grant ACR Permissions:
az role assignment create \ --assignee <app-id> \ --role "AcrPush" \ --scope "/subscriptions/<subscription-id>/resourceGroups/<rg>/providers/Microsoft.ContainerRegistry/registries/<registry>"
Configure the following secrets in your repository:
AZURE_CLIENT_ID: Azure AD Application Client IDAZURE_TENANT_ID: Azure Tenant IDGH_TOKEN: GitHub Personal Access TokenCODECOV_TOKEN: Codecov access token (optional)SLACK_WEBHOOK_URL: Slack webhook URL (optional)
To use these reusable workflows from another repository, reference them using the full repository path:
# In your project's .github/workflows/deploy.yaml
name: Build and Deploy
on:
push:
branches: [main]
jobs:
build:
# Reference the reusable workflow from this repository
uses: kkho/workflows/.github/workflows/build-push.yaml@main
with:
app_name: "my-application"
system_name: "my-system"
environment: "prod"
container_registry: "ghcr.io"
tags: "ghcr.io/my-system/my-application:latest"
dockerfile: "Dockerfile"
dotnet_version: "8.0.x"
secrets:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
notify:
needs: build
if: always()
uses: kkho/workflows/.github/workflows/slack-message.yaml@main
with:
channel: "#deployments"
message: |
Build completed for ${{ github.repository }}
Status: ${{ needs.build.result == 'success' && 'β
Success' || 'β Failed' }}
Commit: ${{ github.sha }}
color: ${{ needs.build.result == 'success' && 'good' || 'danger' }}
secrets:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}For production use, pin to a specific version instead of @main:
uses: kkho/workflows/.github/workflows/build-push.yaml@v1.2.3
# or use a commit SHA
uses: kkho/workflows/.github/workflows/build-push.yaml@abc123name: Build and Deploy
on:
push:
branches: [main, develop]
jobs:
build:
uses: kkho/workflows/.github/workflows/build-push.yaml@main
with:
app_name: "my-api"
system_name: "payment"
environment: ${{ github.ref == 'refs/heads/main' && 'prod' || 'dev' }}
tags: |
myregistry.azurecr.io/payment-api:${{ github.sha }}
myregistry.azurecr.io/payment-api:latest
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}name: Multi-Environment Deploy
on:
push:
branches: [main, develop, staging]
jobs:
build-dev:
if: github.ref == 'refs/heads/develop'
uses: kkho/workflows/.github/workflows/build-push.yaml@main
with:
app_name: "my-api"
system_name: "payment"
environment: "dev"
tags: "myregistry.azurecr.io/payment-api:dev-${{ github.sha }}"
build-args: "ENVIRONMENT=development,DEBUG=true"
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
build-prod:
if: github.ref == 'refs/heads/main'
uses: kkho/workflows/.github/workflows/build-push.yaml@main
with:
app_name: "my-api"
system_name: "payment"
environment: "prod"
tags: |
myregistry.azurecr.io/payment-api:latest
myregistry.azurecr.io/payment-api:v${{ github.run_number }}
version: "v${{ github.run_number }}"
secrets:
GH_TOKEN: ${{ secrets.GH_TOKEN }}
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}steps:
- name: Notify deployment success
uses: your-org/workflows/.github/workflows/slack-message/action.yaml@main
with:
slack-webhook-url: ${{ secrets.SLACK_WEBHOOK_URL }}
channel: "#deployments"
message: "π Successfully deployed ${{ github.repository }} to production!"The workflow supports flexible tagging based on environment:
-
Production (
prod):latesttag enabled- Uses semantic versioning if provided
- SHA-based tags for traceability
-
Non-Production:
- Environment-specific tags (
dev_latest,staging_latest) - SHA-based tags for traceability
- Branch-based tags for feature branches
- Environment-specific tags (
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -am 'Add some feature' - Push to the branch:
git push origin feature/my-feature - Submit a pull request
This project is licensed under the terms specified in the LICENSE file.
For questions or issues:
- Check existing Issues
- Create a new issue with detailed information
- Include workflow logs and error messages