Skip to content

Feat: Page Indicator (v1) #1727

Feat: Page Indicator (v1)

Feat: Page Indicator (v1) #1727

name: Build, Test, and Deploy EssentialCSharp.Web
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:
permissions:
id-token: write
contents: read
jobs:
build-and-test:
runs-on: ubuntu-latest
environment: "BuildAndUploadImage"
env:
TEST_TAG: user/app:test
steps:
- uses: actions/checkout@v4
- name: Set up .NET Core
uses: actions/setup-dotnet@v4
with:
global-json-file: global.json
source-url: https://pkgs.dev.azure.com/intelliTect/_packaging/EssentialCSharp/nuget/v3/index.json
env:
NUGET_AUTH_TOKEN: ${{ secrets.AZURE_DEVOPS_PAT }}
- name: Set up dependency caching for faster builds
uses: actions/cache@v4
id: nuget-cache
with:
path: |
~/.nuget/packages
${{ github.workspace }}/**/obj/project.assets.json
key: ${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
restore-keys: |
${{ runner.os }}-nuget-${{ hashFiles('**/packages.lock.json') }}
${{ runner.os }}-nuget-
- name: Restore with dotnet
run: dotnet restore
- name: Build with dotnet
run: dotnet build --configuration Release --no-restore
- name: Run .NET Tests
run: dotnet test --no-build --configuration Release
- name: Set up Docker Buildx
if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request'
uses: docker/setup-buildx-action@v3
- name: Build Container Image
if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request'
uses: docker/build-push-action@v6
with:
tags: ${{ vars.DEVCONTAINER_REGISTRY }}/essentialcsharpweb:${{ github.sha }},${{ vars.DEVCONTAINER_REGISTRY }}/essentialcsharpweb:latest,${{ vars.PRODCONTAINER_REGISTRY }}/essentialcsharpweb:${{ github.sha }},${{ vars.PRODCONTAINER_REGISTRY }}/essentialcsharpweb:latest
file: ./EssentialCSharp.Web/Dockerfile
context: .
secrets: |
"nuget_auth_token=${{ secrets.AZURE_DEVOPS_PAT }}"
outputs: type=docker,dest=${{ github.workspace }}/essentialcsharpwebimage.tar
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: essentialcsharpwebimage
path: ${{ github.workspace }}/essentialcsharpwebimage.tar
deploy-development:
if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
needs: build-and-test
environment:
name: "Development"
steps:
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ secrets.ESSENTIALCSHARPDEV_CLIENT_ID }}
tenant-id: ${{ secrets.ESSENTIALCSHARP_APPIDENTITY_TENANT_ID }}
subscription-id: ${{ secrets.ESSENTIALCSHARP_SUBSCRIPTION_ID }}
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: essentialcsharpwebimage
path: ${{ github.workspace }}
- name: Load image
run: |
docker load --input ${{ github.workspace }}/essentialcsharpwebimage.tar
docker image ls -a
- name: Log in to container registry
uses: docker/login-action@v3
with:
registry: ${{ vars.DEVCONTAINER_REGISTRY }}
username: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }}
password: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }}
- name: Push Image to Container Registry
run: docker push --all-tags ${{ vars.DEVCONTAINER_REGISTRY }}/essentialcsharpweb
- name: Create and Deploy to Container App
uses: azure/CLI@v2
env:
CONTAINER_APP_NAME: ${{ vars.CONTAINER_APP_NAME }}
RESOURCEGROUP: ${{ vars.RESOURCEGROUP }}
CONTAINER_REGISTRY: ${{ vars.DEVCONTAINER_REGISTRY }}
CONTAINER_APP_ENVIRONMENT: ${{ vars.CONTAINER_APP_ENVIRONMENT }}
ACR_USERNAME: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }}
ACR_PASSWORD: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }}
with:
inlineScript: |
az config set extension.use_dynamic_install=yes_without_prompt
az containerapp up -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --image $CONTAINER_REGISTRY/essentialcsharpweb:${{ github.sha }} --environment $CONTAINER_APP_ENVIRONMENT --registry-server $CONTAINER_REGISTRY --ingress external --target-port 8080 --registry-username $ACR_USERNAME --registry-password $ACR_PASSWORD
- name: Assign Managed Identity to Container App and Set Secrets and Environment Variables
uses: azure/CLI@v2
env:
CONTAINER_APP_NAME: ${{ vars.CONTAINER_APP_NAME }}
RESOURCEGROUP: ${{ vars.RESOURCEGROUP }}
CONTAINER_REGISTRY: ${{ vars.DEVCONTAINER_REGISTRY }}
CONTAINER_APP_ENVIRONMENT: ${{ vars.CONTAINER_APP_ENVIRONMENT }}
KEYVAULTURI: ${{ secrets.ESSENTIALCSHARP_KEYVAULT_URI }}
MANAGEDIDENTITYID: ${{ secrets.ESSENTIALCSHARP_APPIDENTITY_ID }}
ACR_USERNAME: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }}
ACR_PASSWORD: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }}
AZURECLIENTID: ${{ secrets.IDENTITY_CLIENT_ID }}
with:
inlineScript: |
az containerapp identity assign -n ${{ vars.CONTAINER_APP_NAME }} -g ${{ vars.RESOURCEGROUP }} --user-assigned ${{ vars.CONTAINER_APP_IDENTITY }}
az containerapp secret set -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --secrets github-clientid=keyvaultref:$KEYVAULTURI/secrets/authentication-github-clientid,identityref:$MANAGEDIDENTITYID \
github-clientsecret=keyvaultref:$KEYVAULTURI/secrets/authentication-github-clientsecret,identityref:$MANAGEDIDENTITYID msft-clientid=keyvaultref:$KEYVAULTURI/secrets/authentication-microsoft-clientid,identityref:$MANAGEDIDENTITYID \
msft-clientsecret=keyvaultref:$KEYVAULTURI/secrets/authentication-microsoft-clientsecret,identityref:$MANAGEDIDENTITYID emailsender-apikey=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-apikey,identityref:$MANAGEDIDENTITYID \
emailsender-secret=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-secretkey,identityref:$MANAGEDIDENTITYID emailsender-name=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-sendfromname,identityref:$MANAGEDIDENTITYID \
emailsender-email=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-sendfromemail,identityref:$MANAGEDIDENTITYID connectionstring=keyvaultref:$KEYVAULTURI/secrets/connectionstrings-essentialcsharpwebcontextconnection,identityref:$MANAGEDIDENTITYID \
captcha-sitekey=keyvaultref:$KEYVAULTURI/secrets/captcha-sitekey,identityref:$MANAGEDIDENTITYID captcha-secretkey=keyvaultref:$KEYVAULTURI/secrets/captcha-secretkey,identityref:$MANAGEDIDENTITYID
az containerapp update --name $CONTAINER_APP_NAME --resource-group $RESOURCEGROUP --replace-env-vars Authentication__github__clientId=secretref:github-clientid Authentication__github__clientSecret=secretref:github-clientsecret \
Authentication__microsoft__clientId=secretref:msft-clientid Authentication__microsoft__clientSecret=secretref:msft-clientsecret AuthMessageSender__ApiKey=secretref:emailsender-apikey AuthMessageSender__SecretKey=secretref:emailsender-secret \
AuthMessageSender__SendFromName=secretref:emailsender-name AuthMessageSender__SendFromEmail=secretref:emailsender-email ConnectionStrings__EssentialCSharpWebContextConnection=secretref:connectionstring ASPNETCORE_ENVIRONMENT=Staging \
AZURE_CLIENT_ID=$AZURECLIENTID HCaptcha__SiteKey=secretref:captcha-sitekey HCaptcha__SecretKey=secretref:captcha-secretkey
- name: Logout of Azure CLI
if: "always()"
uses: azure/CLI@v2
with:
inlineScript: |
az logout
az cache purge
az account clear
deploy-production:
if: github.event_name != 'pull_request_target' && github.event_name != 'pull_request'
runs-on: ubuntu-latest
needs: [deploy-development]
environment:
name: "Production"
steps:
- name: Azure Login
uses: azure/login@v2
with:
client-id: ${{ secrets.ESSENTIALCSHARP_CLIENT_ID }}
tenant-id: ${{ secrets.ESSENTIALCSHARP_TENANT_ID }}
subscription-id: ${{ secrets.ESSENTIALCSHARP_SUBSCRIPTION_ID }}
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: essentialcsharpwebimage
path: ${{ github.workspace }}
- name: Load image
run: |
docker load --input ${{ github.workspace }}/essentialcsharpwebimage.tar
docker image ls -a
- name: Log in to container registry
uses: docker/login-action@v3
with:
registry: ${{ vars.PRODCONTAINER_REGISTRY }}
username: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }}
password: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }}
- name: Push Image to Container Registry
run: docker push --all-tags ${{ vars.PRODCONTAINER_REGISTRY }}/essentialcsharpweb
- name: Create and Deploy to Container App
uses: azure/CLI@v2
env:
CONTAINER_APP_NAME: ${{ vars.CONTAINER_APP_NAME }}
RESOURCEGROUP: ${{ vars.RESOURCEGROUP }}
CONTAINER_REGISTRY: ${{ vars.PRODCONTAINER_REGISTRY }}
CONTAINER_APP_ENVIRONMENT: ${{ vars.CONTAINER_APP_ENVIRONMENT }}
ACR_USERNAME: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }}
ACR_PASSWORD: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }}
with:
inlineScript: |
az config set extension.use_dynamic_install=yes_without_prompt
az containerapp up -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --image $CONTAINER_REGISTRY/essentialcsharpweb:${{ github.sha }} --environment $CONTAINER_APP_ENVIRONMENT --registry-server $CONTAINER_REGISTRY --ingress external --target-port 8080 --registry-username $ACR_USERNAME --registry-password $ACR_PASSWORD
- name: Assign Managed Identity to Container App and Set Secrets and Environment Variables
uses: azure/CLI@v2
env:
CONTAINER_APP_NAME: ${{ vars.CONTAINER_APP_NAME }}
RESOURCEGROUP: ${{ vars.RESOURCEGROUP }}
CONTAINER_REGISTRY: ${{ vars.PRODCONTAINER_REGISTRY }}
CONTAINER_APP_ENVIRONMENT: ${{ vars.CONTAINER_APP_ENVIRONMENT }}
KEYVAULTURI: ${{ secrets.ESSENTIALCSHARP_KEYVAULT_URI }}
MANAGEDIDENTITYID: ${{ secrets.ESSENTIALCSHARP_APPIDENTITY_ID }}
ACR_USERNAME: ${{ secrets.ESSENTIALCSHARP_ACR_USERNAME }}
ACR_PASSWORD: ${{ secrets.ESSENTIALCSHARP_ACR_PASSWORD }}
AZURECLIENTID: ${{ secrets.IDENTITY_CLIENT_ID }}
with:
inlineScript: |
az containerapp identity assign -n ${{ vars.CONTAINER_APP_NAME }} -g ${{ vars.RESOURCEGROUP }} --user-assigned ${{ vars.CONTAINER_APP_IDENTITY }}
az containerapp secret set -n $CONTAINER_APP_NAME -g $RESOURCEGROUP --secrets github-clientid=keyvaultref:$KEYVAULTURI/secrets/authentication-github-clientid,identityref:$MANAGEDIDENTITYID \
github-clientsecret=keyvaultref:$KEYVAULTURI/secrets/authentication-github-clientsecret,identityref:$MANAGEDIDENTITYID msft-clientid=keyvaultref:$KEYVAULTURI/secrets/authentication-microsoft-clientid,identityref:$MANAGEDIDENTITYID \
msft-clientsecret=keyvaultref:$KEYVAULTURI/secrets/authentication-microsoft-clientsecret,identityref:$MANAGEDIDENTITYID emailsender-apikey=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-apikey,identityref:$MANAGEDIDENTITYID \
emailsender-secret=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-secretkey,identityref:$MANAGEDIDENTITYID emailsender-name=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-sendfromname,identityref:$MANAGEDIDENTITYID \
emailsender-email=keyvaultref:$KEYVAULTURI/secrets/authmessagesender-sendfromemail,identityref:$MANAGEDIDENTITYID connectionstring=keyvaultref:$KEYVAULTURI/secrets/connectionstrings-essentialcsharpwebcontextconnection,identityref:$MANAGEDIDENTITYID \
captcha-sitekey=keyvaultref:$KEYVAULTURI/secrets/captcha-sitekey,identityref:$MANAGEDIDENTITYID captcha-secretkey=keyvaultref:$KEYVAULTURI/secrets/captcha-secretkey,identityref:$MANAGEDIDENTITYID
az containerapp update --name $CONTAINER_APP_NAME --resource-group $RESOURCEGROUP --replace-env-vars Authentication__github__clientId=secretref:github-clientid Authentication__github__clientSecret=secretref:github-clientsecret \
Authentication__microsoft__clientId=secretref:msft-clientid Authentication__microsoft__clientSecret=secretref:msft-clientsecret AuthMessageSender__ApiKey=secretref:emailsender-apikey AuthMessageSender__SecretKey=secretref:emailsender-secret \
AuthMessageSender__SendFromName=secretref:emailsender-name AuthMessageSender__SendFromEmail=secretref:emailsender-email ConnectionStrings__EssentialCSharpWebContextConnection=secretref:connectionstring ASPNETCORE_ENVIRONMENT=Production \
AZURE_CLIENT_ID=$AZURECLIENTID HCaptcha__SiteKey=secretref:captcha-sitekey HCaptcha__SecretKey=secretref:captcha-secretkey
- name: Logout of Azure CLI
if: "always()"
uses: azure/CLI@v2
with:
inlineScript: |
az logout
az cache purge
az account clear