From f0a5b55afbb5ca5f53a87d764be11fe93ca6c93e Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 11:05:06 +0100 Subject: [PATCH 01/17] ci: clean up workflows Refs: AB#40145 --- .github/workflows/blank.yml | 12 ------------ ...heduled-cluster-stop.yml => cluster-autostop.yml} | 4 ++-- ...ot_pull-request-cd.yml => continous-delivery.yml} | 4 ++-- ...ull-request-ci.yml => continuous-integration.yml} | 10 +++++----- ...ngbot_docker-build.yml => routine-buildimage.yml} | 2 +- ...environment.yml => routine-deployenvironment.yml} | 2 +- ..._manage-cluster.yml => routine-managecluster.yml} | 2 +- ...rdingbot_dotnet-test.yml => routine-runtests.yml} | 2 +- ...publicrecordingbot_codeql.yml => scan-codeql.yml} | 4 ++-- .../{sonarcloud.yaml => scan-sonarcloud.yml} | 2 +- .../{docker-image-scan.yml => scan-trivy.yml} | 4 ++-- 11 files changed, 18 insertions(+), 30 deletions(-) delete mode 100644 .github/workflows/blank.yml rename .github/workflows/{publicrecordingbot_scheduled-cluster-stop.yml => cluster-autostop.yml} (95%) rename .github/workflows/{publicrecordingbot_pull-request-cd.yml => continous-delivery.yml} (94%) rename .github/workflows/{publicrecordingbot_pull-request-ci.yml => continuous-integration.yml} (96%) rename .github/workflows/{publicrecordingbot_docker-build.yml => routine-buildimage.yml} (98%) rename .github/workflows/{publicrecordingbot_deploy-environment.yml => routine-deployenvironment.yml} (99%) rename .github/workflows/{publicrecordingbot_manage-cluster.yml => routine-managecluster.yml} (99%) rename .github/workflows/{publicrecordingbot_dotnet-test.yml => routine-runtests.yml} (99%) rename .github/workflows/{publicrecordingbot_codeql.yml => scan-codeql.yml} (97%) rename .github/workflows/{sonarcloud.yaml => scan-sonarcloud.yml} (98%) rename .github/workflows/{docker-image-scan.yml => scan-trivy.yml} (94%) diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml deleted file mode 100644 index 510027e19..000000000 --- a/.github/workflows/blank.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: blank - -on: - workflow_dispatch: - -jobs: - EnvironmentDeploy: - runs-on: windows-latest - - steps: - - name: Checkout - uses: actions/checkout@v2 \ No newline at end of file diff --git a/.github/workflows/publicrecordingbot_scheduled-cluster-stop.yml b/.github/workflows/cluster-autostop.yml similarity index 95% rename from .github/workflows/publicrecordingbot_scheduled-cluster-stop.yml rename to .github/workflows/cluster-autostop.yml index 4eec580b2..c031b0221 100644 --- a/.github/workflows/publicrecordingbot_scheduled-cluster-stop.yml +++ b/.github/workflows/cluster-autostop.yml @@ -1,4 +1,4 @@ -name: Scheduled AKS Cluster Stop +name: Cluster - Auto-Stop # Stop the AKS cluster every day at midnight UTC to save costs on: @@ -45,7 +45,7 @@ jobs: stop-cluster: name: Stop AKS Cluster needs: print-info - uses: ./.github/workflows/publicrecordingbot_manage-cluster.yml + uses: ./.github/workflows/routine-managecluster.yml with: action: 'stop' cluster-name: ${{ vars.AKS_CLUSTER_NAME }} diff --git a/.github/workflows/publicrecordingbot_pull-request-cd.yml b/.github/workflows/continous-delivery.yml similarity index 94% rename from .github/workflows/publicrecordingbot_pull-request-cd.yml rename to .github/workflows/continous-delivery.yml index 2cf32b26c..8c0d964c1 100644 --- a/.github/workflows/publicrecordingbot_pull-request-cd.yml +++ b/.github/workflows/continous-delivery.yml @@ -1,4 +1,4 @@ -name: Recording Bot Release Docker Image +name: Continuous Delivery on: push: @@ -62,7 +62,7 @@ jobs: build-fallback: needs: retag-and-push if: needs.retag-and-push.outputs.image-exists == 'false' - uses: ./.github/workflows/publicrecordingbot_docker-build.yml + uses: ./.github/workflows/routine-buildimage.yml permissions: packages: write with: diff --git a/.github/workflows/publicrecordingbot_pull-request-ci.yml b/.github/workflows/continuous-integration.yml similarity index 96% rename from .github/workflows/publicrecordingbot_pull-request-ci.yml rename to .github/workflows/continuous-integration.yml index 6486a1a74..f569a704e 100644 --- a/.github/workflows/publicrecordingbot_pull-request-ci.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,4 +1,4 @@ -name: Recording Bot Pull Request CI +name: Continuous Integration run-name: Pull Request "${{github.event.pull_request.title}}" - Complete CI Pipeline on: @@ -138,7 +138,7 @@ jobs: needs.check-recording-bot-changes.outputs.scripts == 'True' || needs.check-recording-bot-changes.outputs.src == 'True' ) - uses: ./.github/workflows/publicrecordingbot_manage-cluster.yml + uses: ./.github/workflows/routine-managecluster.yml with: action: 'start' cluster-name: ${{ vars.AKS_CLUSTER_NAME }} @@ -156,7 +156,7 @@ jobs: needs.check-recording-bot-changes.outputs.src == 'True' || needs.check-recording-bot-changes.outputs.scripts == 'True' ) - uses: ./.github/workflows/publicrecordingbot_docker-build.yml + uses: ./.github/workflows/routine-buildimage.yml permissions: packages: write with: @@ -171,7 +171,7 @@ jobs: needs.build-docker-image.result == 'success' || needs.check-recording-bot-changes.outputs.deploy == 'True' ) - uses: ./.github/workflows/publicrecordingbot_deploy-environment.yml + uses: ./.github/workflows/routine-deployenvironment.yml with: environment-name: aks-sample port: '28550' @@ -193,7 +193,7 @@ jobs: run-tests: needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-test-environment] if: needs.deploy-to-test-environment.result == 'success' - uses: ./.github/workflows/publicrecordingbot_dotnet-test.yml + uses: ./.github/workflows/routine-runtests.yml with: headless-mode: true test-environment: pr-${{ github.event.number }} diff --git a/.github/workflows/publicrecordingbot_docker-build.yml b/.github/workflows/routine-buildimage.yml similarity index 98% rename from .github/workflows/publicrecordingbot_docker-build.yml rename to .github/workflows/routine-buildimage.yml index 6997d31fe..39b249a5b 100644 --- a/.github/workflows/publicrecordingbot_docker-build.yml +++ b/.github/workflows/routine-buildimage.yml @@ -1,4 +1,4 @@ -name: Build and Push Docker Image to CR +name: Routine - Build Image on: workflow_call: diff --git a/.github/workflows/publicrecordingbot_deploy-environment.yml b/.github/workflows/routine-deployenvironment.yml similarity index 99% rename from .github/workflows/publicrecordingbot_deploy-environment.yml rename to .github/workflows/routine-deployenvironment.yml index 7ecfdf754..8e2c91bdc 100644 --- a/.github/workflows/publicrecordingbot_deploy-environment.yml +++ b/.github/workflows/routine-deployenvironment.yml @@ -1,4 +1,4 @@ -name: Deploy Teams Recording Bot +name: Routine - Deploy Environment on: workflow_call: diff --git a/.github/workflows/publicrecordingbot_manage-cluster.yml b/.github/workflows/routine-managecluster.yml similarity index 99% rename from .github/workflows/publicrecordingbot_manage-cluster.yml rename to .github/workflows/routine-managecluster.yml index 2a0e49576..647a9bf1b 100644 --- a/.github/workflows/publicrecordingbot_manage-cluster.yml +++ b/.github/workflows/routine-managecluster.yml @@ -1,4 +1,4 @@ -name: Manage AKS Cluster +name: Cluster - Manage # Triggered by other workflows on: diff --git a/.github/workflows/publicrecordingbot_dotnet-test.yml b/.github/workflows/routine-runtests.yml similarity index 99% rename from .github/workflows/publicrecordingbot_dotnet-test.yml rename to .github/workflows/routine-runtests.yml index 11b40f3f9..d3b1c8307 100644 --- a/.github/workflows/publicrecordingbot_dotnet-test.yml +++ b/.github/workflows/routine-runtests.yml @@ -1,4 +1,4 @@ -name: Recording Bot Test +name: Routine - Run Tests on: workflow_call: diff --git a/.github/workflows/publicrecordingbot_codeql.yml b/.github/workflows/scan-codeql.yml similarity index 97% rename from .github/workflows/publicrecordingbot_codeql.yml rename to .github/workflows/scan-codeql.yml index 3214541b0..97817d14e 100644 --- a/.github/workflows/publicrecordingbot_codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -1,4 +1,4 @@ -name: "Recording Bot CodeQL" +name: "Scan - CodeQL" on: push: @@ -10,7 +10,7 @@ on: - main - master schedule: - - cron: "24 5 * * 5" + - cron: "0 0 * * 1" # Every Monday at 00:00 UTC jobs: analyze: diff --git a/.github/workflows/sonarcloud.yaml b/.github/workflows/scan-sonarcloud.yml similarity index 98% rename from .github/workflows/sonarcloud.yaml rename to .github/workflows/scan-sonarcloud.yml index 988fa60c4..d848bec58 100644 --- a/.github/workflows/sonarcloud.yaml +++ b/.github/workflows/scan-sonarcloud.yml @@ -1,4 +1,4 @@ -name: SonarCloud +name: Scan - SonarCloud on: push: branches: diff --git a/.github/workflows/docker-image-scan.yml b/.github/workflows/scan-trivy.yml similarity index 94% rename from .github/workflows/docker-image-scan.yml rename to .github/workflows/scan-trivy.yml index c037b6c90..1c28828a2 100644 --- a/.github/workflows/docker-image-scan.yml +++ b/.github/workflows/scan-trivy.yml @@ -1,8 +1,8 @@ -name: Docker Image Scan +name: Scan - Trivy on: schedule: - - cron: '0 0 * * 1' # Jeden Montag um 00:00 Uhr + - cron: '0 0 * * 1' # Mondays at 00:00 UTC workflow_dispatch: push: branches: From 40b098b22c2be74494f180d663abfb6905ba5ffd Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 11:12:35 +0100 Subject: [PATCH 02/17] ci: add concurrency rule This prevents multiple pull requests from interfering with their respective test runs on the aks environment Refs: AB#40145 --- .github/workflows/continuous-integration.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index f569a704e..bdb754468 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -11,6 +11,10 @@ env: PR_NUMBER: ${{ github.event.number }} IMAGE_TAG: pr-${{ github.event.number }} +concurrency: + group: ci + cancel-in-progress: false + jobs: check-recording-bot-changes: runs-on: ubuntu-latest From cb588eb8fb79ce1a2cf501c9fd203e29f52d9dd5 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 11:14:33 +0100 Subject: [PATCH 03/17] chore: bump versions --- .github/workflows/continuous-integration.yml | 2 +- deploy/teams-recording-bot/Chart.yaml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index bdb754468..93c3ea154 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -12,7 +12,7 @@ env: IMAGE_TAG: pr-${{ github.event.number }} concurrency: - group: ci + group: aks-sample-environment cancel-in-progress: false jobs: diff --git a/deploy/teams-recording-bot/Chart.yaml b/deploy/teams-recording-bot/Chart.yaml index e554be88f..29cd88e9d 100644 --- a/deploy/teams-recording-bot/Chart.yaml +++ b/deploy/teams-recording-bot/Chart.yaml @@ -16,12 +16,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.4.7 +version: 1.4.8 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 1.3.6 +appVersion: 1.3.7 dependencies: - name: ingress-nginx From 5d4c42186f7db1e1dc4d87c51f5b898e9c2dcbdd Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 11:32:50 +0100 Subject: [PATCH 04/17] ci: run tests on chart changes also --- .github/workflows/continuous-integration.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 93c3ea154..af744f0cb 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -170,10 +170,11 @@ jobs: deploy-to-test-environment: needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image] if: | + always() && needs.start-cluster.result == 'success' && ( needs.build-docker-image.result == 'success' || - needs.check-recording-bot-changes.outputs.deploy == 'True' + (needs.check-recording-bot-changes.outputs.deploy == 'True' && needs.build-docker-image.result == 'skipped') ) uses: ./.github/workflows/routine-deployenvironment.yml with: From a73a65f0a1908e84e1db4e9aacc235aa17e1ce20 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 12:12:12 +0100 Subject: [PATCH 05/17] fix: infinite loop during termination Refs: AB#40148 --- scripts/halt_termination.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/halt_termination.ps1 b/scripts/halt_termination.ps1 index 9c45ec84f..23063402c 100644 --- a/scripts/halt_termination.ps1 +++ b/scripts/halt_termination.ps1 @@ -7,8 +7,9 @@ while($continue) try { $result = Invoke-WebRequest -Uri "http://localhost:$CallSignalingPort2/calls" -UseBasicParsing + $calls = $result.Content | ConvertFrom-Json - if ($result.Content) + if ($calls.Count -gt 0) { Start-Sleep -Seconds 60 } From 9c1ef14df9b9355de2db5824c149e59f14a7957e Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 12:12:50 +0100 Subject: [PATCH 06/17] refactor: rename workflow to keep in line with the rest of the workflow names --- .github/workflows/routine-managecluster.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/routine-managecluster.yml b/.github/workflows/routine-managecluster.yml index 647a9bf1b..4f0626215 100644 --- a/.github/workflows/routine-managecluster.yml +++ b/.github/workflows/routine-managecluster.yml @@ -1,4 +1,4 @@ -name: Cluster - Manage +name: Routine - Manage Cluster # Triggered by other workflows on: From 13c9a81b154ea2b1f075da23dceef41b6bb0354f Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 12:24:30 +0100 Subject: [PATCH 07/17] ci: fix improper working directory --- .github/workflows/routine-buildimage.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/routine-buildimage.yml b/.github/workflows/routine-buildimage.yml index 39b249a5b..549760def 100644 --- a/.github/workflows/routine-buildimage.yml +++ b/.github/workflows/routine-buildimage.yml @@ -23,10 +23,6 @@ jobs: permissions: packages: write - defaults: - run: - working-directory: Samples/PublicSamples/RecordingBot - outputs: image-tag: ${{ steps.generate-tag.outputs.tag }} From 6f1be7ec0cca5778862081a193ea4d89b45d210f Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 12:27:17 +0100 Subject: [PATCH 08/17] docs: update paths to reflect new root directory structure --- docs/tutorials/deploy/3-build.md | 6 ------ docs/tutorials/deploy/5-helm.md | 6 ------ 2 files changed, 12 deletions(-) diff --git a/docs/tutorials/deploy/3-build.md b/docs/tutorials/deploy/3-build.md index af2024754..a1057cea6 100644 --- a/docs/tutorials/deploy/3-build.md +++ b/docs/tutorials/deploy/3-build.md @@ -34,12 +34,6 @@ Resolving deltas: 100% (8606/8606), done. Updating files: 100% (1289/1289), done. ``` -Now we navigate to the aks sample in the repository we just downloaded. - -```powershell -cd .\aks-sample\Samples\PublicSamples\RecordingBot\ -``` - ## Build the application To build the application we will push the dockerfile and the source code of the AKS sample to our diff --git a/docs/tutorials/deploy/5-helm.md b/docs/tutorials/deploy/5-helm.md index 1e77569bb..2925bd820 100644 --- a/docs/tutorials/deploy/5-helm.md +++ b/docs/tutorials/deploy/5-helm.md @@ -7,12 +7,6 @@ change the directory since building the Docker container we can continue with [d cd C:\Users\User\recordingbottutorial ``` -And change the directory to the sample project in the repository. - -```powershell -cd .\aks-sample\Samples\PublicSamples\RecordingBot\ -``` - ## Deploy Cert Manager Like any local media bots, the sample needs a properly signed certificate, with a trust chain up to From f94b50eca6dc382dccea0363d0c76919e442b301 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 14:00:25 +0100 Subject: [PATCH 09/17] ci: remove references to master branch --- .github/workflows/continous-delivery.yml | 1 - .github/workflows/continuous-integration.yml | 1 - .github/workflows/scan-codeql.yml | 2 -- 3 files changed, 4 deletions(-) diff --git a/.github/workflows/continous-delivery.yml b/.github/workflows/continous-delivery.yml index 8c0d964c1..e400c22b8 100644 --- a/.github/workflows/continous-delivery.yml +++ b/.github/workflows/continous-delivery.yml @@ -4,7 +4,6 @@ on: push: branches: - main - - master paths: - src - scripts diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index af744f0cb..33b8f43d8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -5,7 +5,6 @@ on: pull_request: branches: - main - - master env: PR_NUMBER: ${{ github.event.number }} diff --git a/.github/workflows/scan-codeql.yml b/.github/workflows/scan-codeql.yml index 97817d14e..d9b6cd108 100644 --- a/.github/workflows/scan-codeql.yml +++ b/.github/workflows/scan-codeql.yml @@ -4,11 +4,9 @@ on: push: branches: - main - - master pull_request: branches: - main - - master schedule: - cron: "0 0 * * 1" # Every Monday at 00:00 UTC From 91a8e5ecb46707c52c3ca4e638de26323ba7c414 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 15:11:01 +0100 Subject: [PATCH 10/17] ci: run tests for main updates + scheduled runs Refs: AB#35620 --- .github/workflows/continous-delivery.yml | 70 -------- .github/workflows/continuous-integration.yml | 178 ++++++++++++++----- 2 files changed, 136 insertions(+), 112 deletions(-) delete mode 100644 .github/workflows/continous-delivery.yml diff --git a/.github/workflows/continous-delivery.yml b/.github/workflows/continous-delivery.yml deleted file mode 100644 index e400c22b8..000000000 --- a/.github/workflows/continous-delivery.yml +++ /dev/null @@ -1,70 +0,0 @@ -name: Continuous Delivery - -on: - push: - branches: - - main - paths: - - src - - scripts - - build - - .github/workflows/publicrecordingbot_pull-request-cd.yml - -jobs: - retag-and-push: - runs-on: ubuntu-latest - - permissions: - packages: write - - steps: - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Generate Docker image tag - id: generate-tag - run: | - hash=$(find ../../src ../../build ../../scripts -type f -exec sha256sum {} \; | sort | sha256sum | awk '{print $1}') - echo "tag=$hash" >> $GITHUB_OUTPUT - - - name: Check if image exists - id: check-image - run: | - if docker manifest inspect ${{ vars.CR_NAMESPACE_REPOSITORY }}:${{ steps.generate-tag.outputs.tag }} > /dev/null 2>&1; then - echo "Image already exists" - echo "image-exists=true" >> $GITHUB_OUTPUT - else - echo "image-exists=false" >> $GITHUB_OUTPUT - fi - - - name: Pull PR image and retag as latest - if: steps.check-image.outputs.image-exists == 'true' - run: | - TAG="${{ steps.generate-tag.outputs.tag }}" - REGISTRY="${{ vars.CR_NAMESPACE_REPOSITORY }}" - - echo "🔍 Pulling image with tag: $TAG" - docker pull ${REGISTRY}:${TAG} - - echo "🏷️ Retagging image as latest" - docker tag ${REGISTRY}:${TAG} ${REGISTRY}:latest - - echo "🚀 Pushing latest image" - docker push ${REGISTRY}:latest - - echo "✅ Successfully promoted ${REGISTRY}:${TAG} to ${REGISTRY}:latest" - - build-fallback: - needs: retag-and-push - if: needs.retag-and-push.outputs.image-exists == 'false' - uses: ./.github/workflows/routine-buildimage.yml - permissions: - packages: write - with: - tag: latest - cr-namespace-repository: ${{ vars.CR_NAMESPACE_REPOSITORY }} - secrets: inherit \ No newline at end of file diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 33b8f43d8..880bf4efc 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -1,14 +1,28 @@ name: Continuous Integration -run-name: Pull Request "${{github.event.pull_request.title}}" - Complete CI Pipeline +run-name: ${{ github.event_name == 'pull_request' && format('Pull Request "{0}" - Complete CI Pipeline', github.event.pull_request.title) || (github.event_name == 'schedule' && 'Scheduled Weekly Deployment and Testing' || format('Main Branch Deploy - {0}', github.sha)) }} on: pull_request: branches: - main + push: + branches: + - main + paths: + - src + - scripts + - build + - deploy + - .github/workflows/continuous-integration.yml + schedule: + # Sunday at 2 PM UTC (Sunday afternoon) + - cron: '0 14 * * 0' env: PR_NUMBER: ${{ github.event.number }} - IMAGE_TAG: pr-${{ github.event.number }} + IMAGE_TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'latest' }} + ENVIRONMENT_NAME: aks-sample + PORT: '28550' concurrency: group: aks-sample-environment @@ -28,30 +42,39 @@ jobs: - shell: pwsh id: changes run: | - # Diff latest commit with latest main commit for Recording Bot - git fetch - git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} - $diff = git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} - - # Check if a file has changed (added, modified, deleted) - $BuildDiff = $diff | Where-Object { $_ -match '^build/' } - $DeployDiff = $diff | Where-Object { $_ -match '^deploy/' } - $DocsDiff = $diff | Where-Object { $_ -match '^docs/' -or $_ -match '.md$' } - $ScriptsDiff = $diff | Where-Object { $_ -match '^scripts/' } - $SrcDiff = $diff | Where-Object { $_ -match '^src/' } - - $HasBuildDiff = $BuildDiff.Length -gt 0 - $HasDeployDiff = $DeployDiff.Length -gt 0 - $HasDocsDiff = $DocsDiff.Length -gt 0 - $HasScriptsDiff = $ScriptsDiff.Length -gt 0 - $HasSrcDiff = $SrcDiff.Length -gt 0 - - # Set the outputs - echo "build=$HasBuildDiff" >> $env:GITHUB_OUTPUT - echo "deploy=$HasDeployDiff" >> $env:GITHUB_OUTPUT - echo "docs=$HasDocsDiff" >> $env:GITHUB_OUTPUT - echo "scripts=$HasScriptsDiff" >> $env:GITHUB_OUTPUT - echo "src=$HasSrcDiff" >> $env:GITHUB_OUTPUT + if ('${{ github.event_name }}' -eq 'push' -or '${{ github.event_name }}' -eq 'schedule') { + # For main branch pushes and scheduled runs, always consider all changes as relevant + echo "build=True" >> $env:GITHUB_OUTPUT + echo "deploy=True" >> $env:GITHUB_OUTPUT + echo "docs=True" >> $env:GITHUB_OUTPUT + echo "scripts=True" >> $env:GITHUB_OUTPUT + echo "src=True" >> $env:GITHUB_OUTPUT + } else { + # For pull requests, check actual changes + git fetch + git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} + $diff = git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} + + # Check if a file has changed (added, modified, deleted) + $BuildDiff = $diff | Where-Object { $_ -match '^build/' } + $DeployDiff = $diff | Where-Object { $_ -match '^deploy/' } + $DocsDiff = $diff | Where-Object { $_ -match '^docs/' -or $_ -match '.md$' } + $ScriptsDiff = $diff | Where-Object { $_ -match '^scripts/' } + $SrcDiff = $diff | Where-Object { $_ -match '^src/' } + + $HasBuildDiff = $BuildDiff.Length -gt 0 + $HasDeployDiff = $DeployDiff.Length -gt 0 + $HasDocsDiff = $DocsDiff.Length -gt 0 + $HasScriptsDiff = $ScriptsDiff.Length -gt 0 + $HasSrcDiff = $SrcDiff.Length -gt 0 + + # Set the outputs + echo "build=$HasBuildDiff" >> $env:GITHUB_OUTPUT + echo "deploy=$HasDeployDiff" >> $env:GITHUB_OUTPUT + echo "docs=$HasDocsDiff" >> $env:GITHUB_OUTPUT + echo "scripts=$HasScriptsDiff" >> $env:GITHUB_OUTPUT + echo "src=$HasSrcDiff" >> $env:GITHUB_OUTPUT + } chart-version-checks: runs-on: ubuntu-latest @@ -89,12 +112,15 @@ jobs: helm lint echo "✅ Helm chart lint passed" - - name: Check App Version Change + - name: Check App Version Change (PR only) id: app-version-check if: | - needs.check-recording-bot-changes.outputs.build == 'True' || - needs.check-recording-bot-changes.outputs.scripts == 'True' || - needs.check-recording-bot-changes.outputs.src == 'True' + github.event_name == 'pull_request' && + ( + needs.check-recording-bot-changes.outputs.build == 'True' || + needs.check-recording-bot-changes.outputs.scripts == 'True' || + needs.check-recording-bot-changes.outputs.src == 'True' + ) shell: bash run: | echo "🔍 Checking app version changes..." @@ -112,8 +138,8 @@ jobs: [ "$newerVersion" = "$newVersion" ] || exit 1 echo "✅ Success app Version was updated!" - - name: Check Chart Version Change - if: needs.check-recording-bot-changes.outputs.deploy == 'True' + - name: Check Chart Version Change (PR only) + if: github.event_name == 'pull_request' && needs.check-recording-bot-changes.outputs.deploy == 'True' shell: bash run: | echo "🔍 Checking chart version changes..." @@ -131,6 +157,67 @@ jobs: [ "$newerVersion" = "$newVersion" ] || exit 1 echo "✅ Success Version was updated!" + retag-and-push: + runs-on: ubuntu-latest + needs: [check-recording-bot-changes, chart-version-checks] + if: | + (github.event_name == 'push' || github.event_name == 'schedule') && + needs.chart-version-checks.result == 'success' && + ( + needs.check-recording-bot-changes.outputs.build == 'True' || + needs.check-recording-bot-changes.outputs.scripts == 'True' || + needs.check-recording-bot-changes.outputs.src == 'True' + ) + + permissions: + packages: write + + outputs: + image-exists: ${{ steps.check-image.outputs.image-exists }} + + steps: + - uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate Docker image tag + id: generate-tag + run: | + hash=$(find src build scripts -type f -exec sha256sum {} \; | sort | sha256sum | awk '{print $1}') + echo "tag=$hash" >> $GITHUB_OUTPUT + + - name: Check if image exists + id: check-image + run: | + if docker manifest inspect ${{ vars.CR_NAMESPACE_REPOSITORY }}:${{ steps.generate-tag.outputs.tag }} > /dev/null 2>&1; then + echo "Image already exists" + echo "image-exists=true" >> $GITHUB_OUTPUT + else + echo "image-exists=false" >> $GITHUB_OUTPUT + fi + + - name: Pull PR image and retag as latest + if: steps.check-image.outputs.image-exists == 'true' + run: | + TAG="${{ steps.generate-tag.outputs.tag }}" + REGISTRY="${{ vars.CR_NAMESPACE_REPOSITORY }}" + + echo "🔍 Pulling image with tag: $TAG" + docker pull ${REGISTRY}:${TAG} + + echo "🏷️ Retagging image as latest" + docker tag ${REGISTRY}:${TAG} ${REGISTRY}:latest + + echo "🚀 Pushing latest image" + docker push ${REGISTRY}:latest + + echo "✅ Successfully promoted ${REGISTRY}:${TAG} to ${REGISTRY}:latest" + start-cluster: needs: [check-recording-bot-changes, chart-version-checks] if: | @@ -151,34 +238,41 @@ jobs: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} build-docker-image: - needs: [check-recording-bot-changes, chart-version-checks] + needs: [check-recording-bot-changes, chart-version-checks, retag-and-push] if: | + always() && needs.chart-version-checks.result == 'success' && ( needs.check-recording-bot-changes.outputs.build == 'True' || needs.check-recording-bot-changes.outputs.src == 'True' || needs.check-recording-bot-changes.outputs.scripts == 'True' + ) && + ( + github.event_name == 'pull_request' || + ((github.event_name == 'push' || github.event_name == 'schedule') && needs.retag-and-push.outputs.image-exists == 'false') ) uses: ./.github/workflows/routine-buildimage.yml permissions: packages: write with: + tag: ${{ env.IMAGE_TAG }} cr-namespace-repository: ${{ vars.CR_NAMESPACE_REPOSITORY }} secrets: inherit - deploy-to-test-environment: - needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image] + deploy-to-environment: + needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, retag-and-push] if: | always() && needs.start-cluster.result == 'success' && ( needs.build-docker-image.result == 'success' || - (needs.check-recording-bot-changes.outputs.deploy == 'True' && needs.build-docker-image.result == 'skipped') + (needs.retag-and-push.result == 'success' && (github.event_name == 'push' || github.event_name == 'schedule')) || + (needs.check-recording-bot-changes.outputs.deploy == 'True' && (needs.build-docker-image.result == 'skipped' || needs.retag-and-push.result == 'skipped')) ) uses: ./.github/workflows/routine-deployenvironment.yml with: - environment-name: aks-sample - port: '28550' + environment-name: ${{ env.ENVIRONMENT_NAME }} + port: ${{ env.PORT }} cluster-name: ${{ vars.AKS_CLUSTER_NAME }} resource-group: ${{ vars.AKS_RESOURCE_GROUP }} subscription: ${{ vars.AZURE_SUBSCRIPTION_ID }} @@ -195,13 +289,13 @@ jobs: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} run-tests: - needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-test-environment] - if: needs.deploy-to-test-environment.result == 'success' + needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-environment, retag-and-push] + if: needs.deploy-to-environment.result == 'success' uses: ./.github/workflows/routine-runtests.yml with: headless-mode: true - test-environment: pr-${{ github.event.number }} - github-issue-number: ${{ github.event.number }} + test-environment: ${{ env.IMAGE_TAG }} + github-issue-number: ${{ github.event.number || '' }} secrets: USER_A_USERNAME: ${{ vars.TEST_USER_A_USERNAME }} USER_A_PASSWORD: ${{ secrets.TEST_USER_A_PASSWORD }} From 840327bf1b95a83174d60cab95033685429135d9 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 15:15:19 +0100 Subject: [PATCH 11/17] ci: fix broken workflow file --- .github/workflows/continuous-integration.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 880bf4efc..b3846e570 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -20,9 +20,6 @@ on: env: PR_NUMBER: ${{ github.event.number }} - IMAGE_TAG: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'latest' }} - ENVIRONMENT_NAME: aks-sample - PORT: '28550' concurrency: group: aks-sample-environment @@ -255,7 +252,7 @@ jobs: permissions: packages: write with: - tag: ${{ env.IMAGE_TAG }} + tag: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'latest' }} cr-namespace-repository: ${{ vars.CR_NAMESPACE_REPOSITORY }} secrets: inherit @@ -271,8 +268,8 @@ jobs: ) uses: ./.github/workflows/routine-deployenvironment.yml with: - environment-name: ${{ env.ENVIRONMENT_NAME }} - port: ${{ env.PORT }} + environment-name: aks-sample + port: '28550' cluster-name: ${{ vars.AKS_CLUSTER_NAME }} resource-group: ${{ vars.AKS_RESOURCE_GROUP }} subscription: ${{ vars.AZURE_SUBSCRIPTION_ID }} @@ -294,7 +291,7 @@ jobs: uses: ./.github/workflows/routine-runtests.yml with: headless-mode: true - test-environment: ${{ env.IMAGE_TAG }} + test-environment: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'latest' }} github-issue-number: ${{ github.event.number || '' }} secrets: USER_A_USERNAME: ${{ vars.TEST_USER_A_USERNAME }} From 4c51e62dd503268175e29be1958be43fd2b052b0 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 15:49:05 +0100 Subject: [PATCH 12/17] docs: status badge for ci in readme Refs: AB#35620 --- README.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 53911d2d2..a44d02df9 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,5 @@ -> [!NOTE] -> Public Samples are provided by developers from the Microsoft Graph community. -> Public Samples are not official Microsoft Communication samples, and not supported by the Microsoft Communication engineering team. It is recommended that you contact the sample owner before using code from Public Samples in production systems. - ---- +# AKS-Sample +[![Continuous Integration](https://github.com/LM-Development/aks-sample/actions/workflows/continuous-integration.yml/badge.svg?branch=main)](https://github.com/LM-Development/aks-sample/actions/workflows/continuous-integration.yml) **Title:** RecordingBot From 6bf0b03c96180b5c56c6022d3b86923973e41619 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 16:02:27 +0100 Subject: [PATCH 13/17] feat: halt termination logging Refs: AB#40148 --- deploy/teams-recording-bot/templates/deployment.yaml | 2 +- scripts/halt_termination.ps1 | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/deploy/teams-recording-bot/templates/deployment.yaml b/deploy/teams-recording-bot/templates/deployment.yaml index dcbea75ea..8af298934 100644 --- a/deploy/teams-recording-bot/templates/deployment.yaml +++ b/deploy/teams-recording-bot/templates/deployment.yaml @@ -60,7 +60,7 @@ spec: command: - powershell - Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine; - - .\halt_termination.ps1 + - .\halt_termination.ps1 *>> halt_termination.log ports: - containerPort: {{ .Values.internal.port }} - containerPort: {{ .Values.internal.media }} diff --git a/scripts/halt_termination.ps1 b/scripts/halt_termination.ps1 index 23063402c..d14949dcb 100644 --- a/scripts/halt_termination.ps1 +++ b/scripts/halt_termination.ps1 @@ -6,20 +6,25 @@ while($continue) { try { + Write-Host "Calling endpoint to check for active calls..." $result = Invoke-WebRequest -Uri "http://localhost:$CallSignalingPort2/calls" -UseBasicParsing + + Write-Host "Response content: $($result.Content)" $calls = $result.Content | ConvertFrom-Json if ($calls.Count -gt 0) { + Write-Host "Active calls detected. Halting termination." Start-Sleep -Seconds 60 } else { + Write-Host "No active calls. Proceeding with termination." $continue = $false } } catch { - "Error while calling endpoint." + Write-Host "Error while calling endpoint." } } From c392d72e22d9e1c37072aba2468b011968d5c16d Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 16:04:50 +0100 Subject: [PATCH 14/17] chore: bump version --- deploy/teams-recording-bot/Chart.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/teams-recording-bot/Chart.yaml b/deploy/teams-recording-bot/Chart.yaml index 29cd88e9d..403072850 100644 --- a/deploy/teams-recording-bot/Chart.yaml +++ b/deploy/teams-recording-bot/Chart.yaml @@ -16,12 +16,12 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.4.8 +version: 1.5.0 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. -appVersion: 1.3.7 +appVersion: 1.4.0 dependencies: - name: ingress-nginx From 6bf625c56fca3df81f5b16b3c6af9b4d7916e4fc Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 16:10:08 +0100 Subject: [PATCH 15/17] ci: ensure tests are running after deployment --- .github/workflows/continuous-integration.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index b3846e570..334a05394 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -286,8 +286,8 @@ jobs: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} run-tests: - needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-environment, retag-and-push] - if: needs.deploy-to-environment.result == 'success' + needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-environment] + if: always() && needs.deploy-to-environment.result == 'success' uses: ./.github/workflows/routine-runtests.yml with: headless-mode: true From 5bf692c234259d2b2b1a9abb7efb2c9d6eb6f1eb Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 16:30:29 +0100 Subject: [PATCH 16/17] ci: use path hashing for pr image tags --- .github/workflows/continuous-integration.yml | 44 +++++++++++++++++--- 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 334a05394..684413db8 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -234,8 +234,40 @@ jobs: secrets: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} - build-docker-image: + generate-image-tag: needs: [check-recording-bot-changes, chart-version-checks, retag-and-push] + if: | + always() && + needs.chart-version-checks.result == 'success' && + ( + needs.check-recording-bot-changes.outputs.build == 'True' || + needs.check-recording-bot-changes.outputs.src == 'True' || + needs.check-recording-bot-changes.outputs.scripts == 'True' + ) && + ( + github.event_name == 'pull_request' || + ((github.event_name == 'push' || github.event_name == 'schedule') && needs.retag-and-push.outputs.image-exists == 'false') + ) + runs-on: ubuntu-latest + + outputs: + image-tag: ${{ steps.generate-tag.outputs.tag }} + + steps: + - uses: actions/checkout@v4 + + - name: Generate content-based image tag + id: generate-tag + run: | + hash=$(find src build scripts -type f -exec sha256sum {} \; | sort | sha256sum | awk '{print $1}') + if [ '${{ github.event_name }}' = 'pull_request' ]; then + echo "tag=pr-${{ github.event.number }}-${hash:0:8}" >> $GITHUB_OUTPUT + else + echo "tag=latest" >> $GITHUB_OUTPUT + fi + + build-docker-image: + needs: [check-recording-bot-changes, chart-version-checks, retag-and-push, generate-image-tag] if: | always() && needs.chart-version-checks.result == 'success' && @@ -252,12 +284,12 @@ jobs: permissions: packages: write with: - tag: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'latest' }} + tag: ${{ needs.generate-image-tag.outputs.image-tag }} cr-namespace-repository: ${{ vars.CR_NAMESPACE_REPOSITORY }} secrets: inherit deploy-to-environment: - needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, retag-and-push] + needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, retag-and-push, generate-image-tag] if: | always() && needs.start-cluster.result == 'success' && @@ -277,7 +309,7 @@ jobs: host: ${{ needs.start-cluster.outputs.cluster-fqdn }} image-registry: ${{ vars.CR_REGISTRY }} image-name: ${{ vars.CR_IMAGE_NAME }} - image-tag: ${{ needs.build-docker-image.outputs.image-tag || 'latest' }} + image-tag: ${{ needs.generate-image-tag.outputs.image-tag || 'latest' }} public-ip: ${{ needs.start-cluster.outputs.cluster-ip }} tls-email: ${{ vars.TLS_EMAIL }} enable-nginx: true @@ -286,12 +318,12 @@ jobs: AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }} run-tests: - needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-environment] + needs: [check-recording-bot-changes, chart-version-checks, start-cluster, build-docker-image, deploy-to-environment, generate-image-tag] if: always() && needs.deploy-to-environment.result == 'success' uses: ./.github/workflows/routine-runtests.yml with: headless-mode: true - test-environment: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || 'latest' }} + test-environment: ${{ needs.generate-image-tag.outputs.image-tag || 'latest' }} github-issue-number: ${{ github.event.number || '' }} secrets: USER_A_USERNAME: ${{ vars.TEST_USER_A_USERNAME }} From c8fe095be8b5c577fb94e8b0684b02f3bd8af194 Mon Sep 17 00:00:00 2001 From: InDieTasten Date: Tue, 6 Jan 2026 17:13:42 +0100 Subject: [PATCH 17/17] feat: improved exception logging in halt script --- scripts/halt_termination.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/halt_termination.ps1 b/scripts/halt_termination.ps1 index d14949dcb..2f83b63ea 100644 --- a/scripts/halt_termination.ps1 +++ b/scripts/halt_termination.ps1 @@ -25,6 +25,7 @@ while($continue) } catch { - Write-Host "Error while calling endpoint." + Write-Host "Error while calling endpoint: $_" + Start-Sleep -Seconds 10 } }