Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions .github/workflows/blank.yml

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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:
Expand Down Expand Up @@ -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 }}
Expand Down
337 changes: 337 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,337 @@
name: Continuous Integration
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 }}

concurrency:
group: aks-sample-environment
cancel-in-progress: false

jobs:
check-recording-bot-changes:
runs-on: ubuntu-latest
outputs:
build: ${{ steps.changes.outputs.build }}
deploy: ${{ steps.changes.outputs.deploy }}
docs: ${{ steps.changes.outputs.docs }}
scripts: ${{ steps.changes.outputs.scripts }}
src: ${{ steps.changes.outputs.src }}
steps:
- uses: actions/checkout@v4
- shell: pwsh
id: changes
run: |
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
needs: check-recording-bot-changes
if: |
needs.check-recording-bot-changes.outputs.build == 'True' ||
needs.check-recording-bot-changes.outputs.deploy == 'True' ||
needs.check-recording-bot-changes.outputs.scripts == 'True' ||
needs.check-recording-bot-changes.outputs.src == 'True'

defaults:
run:
working-directory: deploy

outputs:
app-version-check-passed: ${{ steps.app-version-check.outcome }}
chart-version-check-passed: ${{ steps.chart-version-check.outcome }}

steps:
- uses: actions/checkout@v4
- run: |
git fetch
git branch -a

- name: Install Helm
uses: azure/setup-helm@v3
with:
version: 'latest'

- name: Lint Helm Chart
working-directory: deploy/teams-recording-bot
if: needs.check-recording-bot-changes.outputs.deploy == 'True'
run: |
echo "🔍 Linting Helm chart..."
helm lint
echo "✅ Helm chart lint passed"

- name: Check App Version Change (PR only)
id: app-version-check
if: |
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..."
oldVersion=$(MSYS_NO_PATHCONV=1 git show remotes/origin/$GITHUB_BASE_REF:deploy/teams-recording-bot/Chart.yaml | sed -n "s/^appVersion: \([0-9\.]*\)$/\1/p")
echo "Previous app Version: $oldVersion"
[ -z "$oldVersion" ] && exit 1

newVersion=$(cat teams-recording-bot/Chart.yaml | sed -n "s/^appVersion: \([0-9\.]*\)$/\1/p")
echo "New app Version: $newVersion"
[ -z "$newVersion" ] && exit 1

echo "Check if app Version was updated"
[ "$newVersion" = "$oldVersion" ] && exit 1
newerVersion=$(echo -e "$oldVersion\n$newVersion" | sort -V | tail -1)
[ "$newerVersion" = "$newVersion" ] || exit 1
echo "✅ Success app Version was updated!"

- 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..."
oldVersion=$(MSYS_NO_PATHCONV=1 git show remotes/origin/$GITHUB_BASE_REF:deploy/teams-recording-bot/Chart.yaml | sed -n "s/^version: \([0-9\.]*\)$/\1/p")
echo "Previous Version: $oldVersion"
[ -z "$oldVersion" ] && exit 1

newVersion=$(cat teams-recording-bot/Chart.yaml | sed -n "s/^version: \([0-9\.]*\)$/\1/p")
echo "New Version: $newVersion"
[ -z "$newVersion" ] && exit 1

echo "Check if Version was updated"
[ "$newVersion" = "$oldVersion" ] && exit 1
newerVersion=$(echo -e "$oldVersion\n$newVersion" | sort -V | tail -1)
[ "$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: |
needs.chart-version-checks.result == 'success' &&
(
needs.check-recording-bot-changes.outputs.build == 'True' ||
needs.check-recording-bot-changes.outputs.deploy == 'True' ||
needs.check-recording-bot-changes.outputs.scripts == 'True' ||
needs.check-recording-bot-changes.outputs.src == 'True'
)
uses: ./.github/workflows/routine-managecluster.yml
with:
action: 'start'
cluster-name: ${{ vars.AKS_CLUSTER_NAME }}
resource-group: ${{ vars.AKS_RESOURCE_GROUP }}
subscription: ${{ vars.AZURE_SUBSCRIPTION_ID }}
secrets:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}

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' &&
(
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: ${{ 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, generate-image-tag]
if: |
always() &&
needs.start-cluster.result == 'success' &&
(
needs.build-docker-image.result == 'success' ||
(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'
cluster-name: ${{ vars.AKS_CLUSTER_NAME }}
resource-group: ${{ vars.AKS_RESOURCE_GROUP }}
subscription: ${{ vars.AZURE_SUBSCRIPTION_ID }}
namespace: teams-recording-bot
host: ${{ needs.start-cluster.outputs.cluster-fqdn }}
image-registry: ${{ vars.CR_REGISTRY }}
image-name: ${{ vars.CR_IMAGE_NAME }}
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
replica-count: '1'
secrets:
AZURE_CREDENTIALS: ${{ secrets.AZURE_CREDENTIALS }}

run-tests:
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: ${{ needs.generate-image-tag.outputs.image-tag || 'latest' }}
github-issue-number: ${{ github.event.number || '' }}
secrets:
USER_A_USERNAME: ${{ vars.TEST_USER_A_USERNAME }}
USER_A_PASSWORD: ${{ secrets.TEST_USER_A_PASSWORD }}
USER_A_SEED: ${{ secrets.TEST_USER_A_SEED }}
USER_B_USERNAME: ${{ vars.TEST_USER_B_USERNAME }}
USER_B_PASSWORD: ${{ secrets.TEST_USER_B_PASSWORD }}
USER_B_SEED: ${{ secrets.TEST_USER_B_SEED }}
USER_C_USERNAME: ${{ vars.TEST_USER_C_USERNAME }}
USER_C_PASSWORD: ${{ secrets.TEST_USER_C_PASSWORD }}
USER_C_SEED: ${{ secrets.TEST_USER_C_SEED }}
Loading
Loading